chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
incident_mode: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Filter actions by incident mode (standard, retrospective, test, tutorial, or stream)',
|
||||
},
|
||||
},
|
||||
|
||||
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.trim())
|
||||
}
|
||||
|
||||
if (params.incident_mode) {
|
||||
url.searchParams.append('incident_mode', params.incident_mode)
|
||||
}
|
||||
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/actions/${params.id.trim()}`,
|
||||
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 (e.g., "Affected Service")',
|
||||
},
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/custom_fields/${params.id.trim()}`,
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/custom_fields/${params.id.trim()}`,
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the custom field (e.g., "Affected Service")',
|
||||
},
|
||||
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.trim()}`,
|
||||
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,134 @@
|
||||
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 (e.g., "Critical Incident 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, unknown> = {
|
||||
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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id.trim()}`,
|
||||
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,96 @@
|
||||
import type {
|
||||
IncidentioEscalationPathsListParams,
|
||||
IncidentioEscalationPathsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const escalationPathsListTool: ToolConfig<
|
||||
IncidentioEscalationPathsListParams,
|
||||
IncidentioEscalationPathsListResponse
|
||||
> = {
|
||||
id: 'incidentio_escalation_paths_list',
|
||||
name: 'List Escalation Paths',
|
||||
description: 'List escalation paths 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-or-llm',
|
||||
description: 'Number of escalation paths to return per page',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor to fetch the next page of results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/escalation_paths')
|
||||
if (params.page_size) url.searchParams.set('page_size', 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: {
|
||||
escalation_paths: data.escalation_paths ?? [],
|
||||
pagination_meta: data.pagination_meta
|
||||
? {
|
||||
after: data.pagination_meta.after,
|
||||
page_size: data.pagination_meta.page_size,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalation_paths: {
|
||||
type: 'array',
|
||||
description: 'List of escalation paths',
|
||||
items: {
|
||||
type: 'object',
|
||||
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' },
|
||||
working_hours: {
|
||||
type: 'array',
|
||||
description: 'Working hours configuration',
|
||||
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,109 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalation_paths/${params.id.trim()}`,
|
||||
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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the escalation path (e.g., "Critical Incident Path")',
|
||||
},
|
||||
path: {
|
||||
type: 'json',
|
||||
required: true,
|
||||
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.trim()}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
name: params.name,
|
||||
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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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 (e.g., "Database Critical Alert")',
|
||||
},
|
||||
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,95 @@
|
||||
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-or-llm',
|
||||
description: 'Number of escalations to return per page',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor to fetch the next page of results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/escalations')
|
||||
if (params.page_size) url.searchParams.set('page_size', 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: {
|
||||
escalations: data.escalations || [],
|
||||
pagination_meta: data.pagination_meta
|
||||
? {
|
||||
after: data.pagination_meta.after,
|
||||
page_size: data.pagination_meta.page_size,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
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,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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/escalations/${params.id.trim()}`,
|
||||
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,172 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
incident_mode: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Filter follow-ups by incident mode (standard, retrospective, test, tutorial, or stream)',
|
||||
},
|
||||
},
|
||||
|
||||
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.trim())
|
||||
}
|
||||
|
||||
if (params.incident_mode) {
|
||||
url.searchParams.append('incident_mode', params.incident_mode)
|
||||
}
|
||||
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/follow_ups/${params.id.trim()}`,
|
||||
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 (e.g., "Incident Commander")',
|
||||
},
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_roles/${params.id.trim()}`,
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_roles/${params.id.trim()}`,
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the incident role (e.g., "Incident Commander")',
|
||||
},
|
||||
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.trim()}`,
|
||||
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 {
|
||||
IncidentioIncidentStatusesListParams,
|
||||
IncidentioIncidentStatusesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incident_timestamps/${params.id.trim()}`,
|
||||
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 {
|
||||
IncidentioIncidentTypesListParams,
|
||||
IncidentioIncidentTypesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/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,135 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0"). If not provided, returns all updates',
|
||||
},
|
||||
page_size: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return per page (e.g., 10, 25, 50)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Cursor for pagination (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/incident_updates')
|
||||
|
||||
if (params.incident_id) {
|
||||
url.searchParams.set('incident_id', params.incident_id.trim())
|
||||
}
|
||||
|
||||
if (params.page_size) {
|
||||
url.searchParams.set('page_size', params.page_size.toString())
|
||||
}
|
||||
|
||||
if (params.after) {
|
||||
url.searchParams.set('after', params.after.trim())
|
||||
}
|
||||
|
||||
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: {
|
||||
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,184 @@
|
||||
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 (e.g., "Database connection issues")',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Brief summary of the incident (e.g., "Intermittent connection failures to primary database")',
|
||||
},
|
||||
severity_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the severity level (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
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,152 @@
|
||||
import type {
|
||||
IncidentioIncidentsListParams,
|
||||
IncidentioIncidentsListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import {
|
||||
INCIDENTIO_INCIDENT_OUTPUT_PROPERTIES,
|
||||
INCIDENTIO_PAGINATION_OUTPUT_PROPERTIES,
|
||||
} 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-or-llm',
|
||||
description: 'Number of incidents to return per page (e.g., 10, 25, 50). Default: 25',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Pagination cursor to fetch the next page of results (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
sort_by: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Sort order for incidents: created_at_newest_first or created_at_oldest_first',
|
||||
},
|
||||
filter_mode: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'How to combine filters: all or any',
|
||||
},
|
||||
},
|
||||
|
||||
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.trim())
|
||||
}
|
||||
|
||||
if (params.sort_by) {
|
||||
url.searchParams.append('sort_by', params.sort_by)
|
||||
}
|
||||
|
||||
if (params.filter_mode) {
|
||||
url.searchParams.append('filter_mode', params.filter_mode)
|
||||
}
|
||||
|
||||
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: INCIDENTIO_INCIDENT_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination metadata',
|
||||
optional: true,
|
||||
properties: INCIDENTIO_PAGINATION_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/incidents/${params.id.trim()}`,
|
||||
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,185 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated name of the incident (e.g., "Database connection issues")',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Updated summary of the incident (e.g., "Intermittent connection failures to primary database")',
|
||||
},
|
||||
severity_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated severity ID for the incident (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
incident_status_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated status ID for the incident (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
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.trim()}/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,95 @@
|
||||
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 { escalationPathsListTool } from '@/tools/incidentio/escalation_paths_list'
|
||||
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 incidentioEscalationPathsListTool = escalationPathsListTool
|
||||
export const incidentioEscalationPathsCreateTool = escalationPathsCreateTool
|
||||
export const incidentioEscalationPathsShowTool = escalationPathsShowTool
|
||||
export const incidentioEscalationPathsUpdateTool = escalationPathsUpdateTool
|
||||
export const incidentioEscalationPathsDeleteTool = escalationPathsDeleteTool
|
||||
|
||||
export * from '@/tools/incidentio/types'
|
||||
@@ -0,0 +1,104 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
entry_window_start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Start date/time to filter entries in ISO 8601 format (e.g., "2024-01-15T09:00:00Z")',
|
||||
},
|
||||
entry_window_end: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'End date/time to filter entries in ISO 8601 format (e.g., "2024-01-22T09:00:00Z")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/schedule_entries')
|
||||
|
||||
url.searchParams.set('schedule_id', params.schedule_id.trim())
|
||||
|
||||
if (params.entry_window_start) {
|
||||
url.searchParams.set('entry_window_start', params.entry_window_start)
|
||||
}
|
||||
|
||||
if (params.entry_window_end) {
|
||||
url.searchParams.set('entry_window_end', params.entry_window_end)
|
||||
}
|
||||
|
||||
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: {
|
||||
schedule_entries: {
|
||||
final: data.schedule_entries?.final ?? [],
|
||||
overrides: data.schedule_entries?.overrides ?? [],
|
||||
scheduled: data.schedule_entries?.scheduled ?? [],
|
||||
},
|
||||
pagination_meta: data.pagination_meta,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedule_entries: {
|
||||
type: 'object',
|
||||
description: 'Schedule entries grouped by final, overrides, and scheduled entries',
|
||||
properties: {
|
||||
final: { type: 'array', description: 'Final computed schedule entries' },
|
||||
overrides: { type: 'array', description: 'Override schedule entries' },
|
||||
scheduled: { type: 'array', description: 'Scheduled entries before overrides are applied' },
|
||||
},
|
||||
},
|
||||
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 },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
layer_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the layer this override applies to',
|
||||
},
|
||||
schedule_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the schedule (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
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 in ISO 8601 format (e.g., "2024-01-15T09:00:00Z")',
|
||||
},
|
||||
end_at: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'When the override ends in ISO 8601 format (e.g., "2024-01-22T09:00:00Z")',
|
||||
},
|
||||
},
|
||||
|
||||
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 {
|
||||
layer_id: params.layer_id.trim(),
|
||||
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' },
|
||||
layer_id: { type: 'string', description: 'The schedule layer 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 (e.g., "Primary On-Call")',
|
||||
},
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/schedules/${params.id.trim()}`,
|
||||
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,98 @@
|
||||
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-or-llm',
|
||||
description: 'Number of results per page (e.g., 10, 25, 50). Default: 25',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Pagination cursor to fetch the next page of results (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/schedules/${params.id.trim()}`,
|
||||
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,93 @@
|
||||
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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the schedule (e.g., "Primary On-Call")',
|
||||
},
|
||||
timezone: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New timezone for the schedule (e.g., America/New_York)',
|
||||
},
|
||||
config: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
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: (params) => `https://api.incident.io/v2/schedules/${params.id.trim()}`,
|
||||
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
|
||||
if (params.config) {
|
||||
schedule.config =
|
||||
typeof params.config === 'string' ? JSON.parse(params.config) : params.config
|
||||
}
|
||||
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,66 @@
|
||||
import type {
|
||||
IncidentioSeveritiesListParams,
|
||||
IncidentioSeveritiesListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
import {
|
||||
INCIDENTIO_PAGINATION_OUTPUT_PROPERTIES,
|
||||
type IncidentioUsersListParams,
|
||||
type IncidentioUsersListResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/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-or-llm',
|
||||
description: 'Number of results to return per page (e.g., 10, 25, 50). Default: 25',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor to fetch the next page of results',
|
||||
},
|
||||
email: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter users by email address',
|
||||
},
|
||||
slack_user_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter users by Slack user ID',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://api.incident.io/v2/users')
|
||||
|
||||
if (params.page_size) {
|
||||
url.searchParams.append('page_size', params.page_size.toString())
|
||||
}
|
||||
|
||||
if (params.after) {
|
||||
url.searchParams.append('after', params.after.trim())
|
||||
}
|
||||
|
||||
if (params.email) {
|
||||
url.searchParams.append('email', params.email.trim())
|
||||
}
|
||||
|
||||
if (params.slack_user_id) {
|
||||
url.searchParams.append('slack_user_id', params.slack_user_id.trim())
|
||||
}
|
||||
|
||||
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: {
|
||||
users: data.users.map((user: any) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
})),
|
||||
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: {
|
||||
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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pagination_meta: {
|
||||
type: 'object',
|
||||
description: 'Pagination metadata',
|
||||
optional: true,
|
||||
properties: INCIDENTIO_PAGINATION_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import type {
|
||||
IncidentioUsersShowParams,
|
||||
IncidentioUsersShowResponse,
|
||||
} from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/users/${params.id.trim()}`,
|
||||
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,70 @@
|
||||
import { getErrorMessage } from '@sim/utils/errors'
|
||||
import type { Workflow } from '@/tools/incidentio/types'
|
||||
|
||||
function toStringValue(value: unknown): string {
|
||||
return typeof value === 'string' ? value : String(value ?? '')
|
||||
}
|
||||
|
||||
function toOptionalStringValue(value: unknown): string | undefined {
|
||||
return typeof value === 'string' && value ? value : undefined
|
||||
}
|
||||
|
||||
function toNumberValue(value: unknown): number {
|
||||
return typeof value === 'number' ? value : Number(value ?? 0)
|
||||
}
|
||||
|
||||
function toBooleanValue(value: unknown): boolean {
|
||||
return value === true
|
||||
}
|
||||
|
||||
function toArrayValue<T = unknown>(value: unknown): T[] {
|
||||
return Array.isArray(value) ? (value as T[]) : []
|
||||
}
|
||||
|
||||
export function parseIncidentioJsonParam(
|
||||
jsonString: string | undefined,
|
||||
paramName: string,
|
||||
defaultValue: unknown
|
||||
): unknown {
|
||||
if (jsonString === undefined || jsonString === '') return defaultValue
|
||||
|
||||
try {
|
||||
return JSON.parse(jsonString)
|
||||
} catch (error) {
|
||||
throw new Error(`Invalid JSON for ${paramName}: ${getErrorMessage(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
export function parseRequiredIncidentioJsonParam(
|
||||
jsonString: string | undefined,
|
||||
paramName: string
|
||||
): unknown {
|
||||
if (jsonString === undefined || jsonString === '') {
|
||||
throw new Error(`Missing required JSON for ${paramName}`)
|
||||
}
|
||||
|
||||
return parseIncidentioJsonParam(jsonString, paramName, undefined)
|
||||
}
|
||||
|
||||
export function mapIncidentioWorkflow(workflow: Record<string, unknown>): Workflow {
|
||||
return {
|
||||
id: toStringValue(workflow.id),
|
||||
name: toStringValue(workflow.name),
|
||||
trigger: toStringValue(workflow.trigger),
|
||||
once_for: toArrayValue(workflow.once_for),
|
||||
version: toNumberValue(workflow.version),
|
||||
expressions: toArrayValue(workflow.expressions),
|
||||
condition_groups: toArrayValue(workflow.condition_groups),
|
||||
steps: toArrayValue(workflow.steps),
|
||||
include_private_incidents: toBooleanValue(workflow.include_private_incidents),
|
||||
include_private_escalations: toBooleanValue(workflow.include_private_escalations),
|
||||
runs_on_incident_modes: toArrayValue<string>(workflow.runs_on_incident_modes),
|
||||
continue_on_step_error: toBooleanValue(workflow.continue_on_step_error),
|
||||
runs_on_incidents: toStringValue(workflow.runs_on_incidents) as Workflow['runs_on_incidents'],
|
||||
state: toStringValue(workflow.state) as Workflow['state'],
|
||||
delay: workflow.delay,
|
||||
folder: toOptionalStringValue(workflow.folder),
|
||||
runs_from: toOptionalStringValue(workflow.runs_from),
|
||||
shortform: toOptionalStringValue(workflow.shortform),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
import type { WorkflowsCreateParams, WorkflowsCreateResponse } from '@/tools/incidentio/types'
|
||||
import { INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES } from '@/tools/incidentio/types'
|
||||
import { mapIncidentioWorkflow, parseIncidentioJsonParam } from '@/tools/incidentio/utils'
|
||||
import type { ToolConfig } from '@/tools/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 (e.g., "Notify on Critical Incidents")',
|
||||
},
|
||||
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: 'draft',
|
||||
},
|
||||
trigger: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Trigger type for the workflow (e.g., "incident.updated", "incident.created")',
|
||||
default: 'incident.updated',
|
||||
},
|
||||
steps: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Array of workflow steps as JSON string. Example: [{"label": "Notify team", "name": "slack.post_message"}]',
|
||||
default: '[]',
|
||||
},
|
||||
condition_groups: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Array of condition groups as JSON string to control when the workflow runs. Example: [{"conditions": [{"operation": "one_of", "param_bindings": [], "subject": "incident.severity"}]}]',
|
||||
default: '[]',
|
||||
},
|
||||
runs_on_incidents: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'When to run the workflow: "newly_created" (only new incidents), "newly_created_and_active" (new and active incidents), "active" (only active incidents), or "all" (all incidents)',
|
||||
default: 'newly_created',
|
||||
},
|
||||
runs_on_incident_modes: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Array of incident modes to run on as JSON string. Example: ["standard", "retrospective"]',
|
||||
default: '["standard"]',
|
||||
},
|
||||
include_private_incidents: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to include private incidents',
|
||||
default: true,
|
||||
},
|
||||
continue_on_step_error: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to continue executing subsequent steps if a step fails',
|
||||
default: false,
|
||||
},
|
||||
once_for: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Array of fields to ensure the workflow runs only once per unique combination of these fields, as JSON string. Example: ["incident.id"]',
|
||||
default: '[]',
|
||||
},
|
||||
expressions: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Array of workflow expressions as JSON string for advanced workflow logic. Example: [{"label": "My expression", "operations": []}]',
|
||||
default: '[]',
|
||||
},
|
||||
delay: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Delay configuration as JSON string. Example: {"for_seconds": 60, "conditions_apply_over_delay": false}',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/workflows',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
name: params.name,
|
||||
trigger: params.trigger || 'incident.updated',
|
||||
once_for: parseIncidentioJsonParam(params.once_for, 'once_for', []),
|
||||
condition_groups: parseIncidentioJsonParam(params.condition_groups, 'condition_groups', []),
|
||||
steps: parseIncidentioJsonParam(params.steps, 'steps', []),
|
||||
expressions: parseIncidentioJsonParam(params.expressions, 'expressions', []),
|
||||
include_private_incidents: params.include_private_incidents ?? true,
|
||||
runs_on_incident_modes: parseIncidentioJsonParam(
|
||||
params.runs_on_incident_modes,
|
||||
'runs_on_incident_modes',
|
||||
['standard']
|
||||
),
|
||||
continue_on_step_error: params.continue_on_step_error ?? false,
|
||||
runs_on_incidents: params.runs_on_incidents || 'newly_created',
|
||||
state: params.state || 'draft',
|
||||
}
|
||||
|
||||
if (params.folder) {
|
||||
body.folder = params.folder
|
||||
}
|
||||
|
||||
if (params.delay) {
|
||||
body.delay = parseIncidentioJsonParam(params.delay, 'delay', undefined)
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
management_meta: data.management_meta,
|
||||
workflow: mapIncidentioWorkflow(data.workflow),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflow: {
|
||||
type: 'object',
|
||||
description: 'The created workflow',
|
||||
properties: INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES,
|
||||
},
|
||||
management_meta: {
|
||||
type: 'json',
|
||||
description: 'Workflow management metadata',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { WorkflowsDeleteParams, WorkflowsDeleteResponse } from '@/tools/incidentio/types'
|
||||
import type { ToolConfig } from '@/tools/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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/workflows/${params.id.trim()}`,
|
||||
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,54 @@
|
||||
import type { WorkflowsListParams, WorkflowsListResponse } from '@/tools/incidentio/types'
|
||||
import { INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES } from '@/tools/incidentio/types'
|
||||
import { mapIncidentioWorkflow } from '@/tools/incidentio/utils'
|
||||
import type { ToolConfig } from '@/tools/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',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.incident.io/v2/workflows',
|
||||
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: Record<string, unknown>) =>
|
||||
mapIncidentioWorkflow(workflow)
|
||||
) ?? [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflows: {
|
||||
type: 'array',
|
||||
description: 'List of workflows',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { WorkflowsShowParams, WorkflowsShowResponse } from '@/tools/incidentio/types'
|
||||
import { INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES } from '@/tools/incidentio/types'
|
||||
import { mapIncidentioWorkflow } from '@/tools/incidentio/utils'
|
||||
import type { ToolConfig } from '@/tools/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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
skip_step_upgrades: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Skip workflow step upgrades when existing workflow step parameters changed',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL(`https://api.incident.io/v2/workflows/${params.id.trim()}`)
|
||||
if (params.skip_step_upgrades !== undefined) {
|
||||
url.searchParams.set('skip_step_upgrades', String(params.skip_step_upgrades))
|
||||
}
|
||||
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: {
|
||||
management_meta: data.management_meta,
|
||||
workflow: mapIncidentioWorkflow(data.workflow),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflow: {
|
||||
type: 'object',
|
||||
description: 'The workflow details',
|
||||
properties: INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES,
|
||||
},
|
||||
management_meta: {
|
||||
type: 'json',
|
||||
description: 'Workflow management metadata',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
import type { WorkflowsUpdateParams, WorkflowsUpdateResponse } from '@/tools/incidentio/types'
|
||||
import { INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES } from '@/tools/incidentio/types'
|
||||
import {
|
||||
mapIncidentioWorkflow,
|
||||
parseIncidentioJsonParam,
|
||||
parseRequiredIncidentioJsonParam,
|
||||
} from '@/tools/incidentio/utils'
|
||||
import type { ToolConfig } from '@/tools/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 (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the workflow (e.g., "Notify on Critical Incidents")',
|
||||
},
|
||||
steps: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Complete array of workflow steps as a JSON string',
|
||||
},
|
||||
condition_groups: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Complete array of workflow condition groups as a JSON string',
|
||||
},
|
||||
runs_on_incidents: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'When to run the workflow: newly_created, newly_created_and_active, active, or all',
|
||||
},
|
||||
runs_on_incident_modes: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Complete array of incident modes to run on as a JSON string',
|
||||
},
|
||||
include_private_incidents: {
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to include private incidents',
|
||||
},
|
||||
continue_on_step_error: {
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to continue executing subsequent steps if a step fails',
|
||||
},
|
||||
once_for: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Complete array of fields that make the workflow run once as a JSON string',
|
||||
},
|
||||
expressions: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Complete array of workflow expressions as a JSON string',
|
||||
},
|
||||
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',
|
||||
},
|
||||
delay: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Delay configuration as a JSON string',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.incident.io/v2/workflows/${params.id.trim()}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
name: params.name,
|
||||
once_for: parseRequiredIncidentioJsonParam(params.once_for, 'once_for'),
|
||||
condition_groups: parseRequiredIncidentioJsonParam(
|
||||
params.condition_groups,
|
||||
'condition_groups'
|
||||
),
|
||||
steps: parseRequiredIncidentioJsonParam(params.steps, 'steps'),
|
||||
expressions: parseRequiredIncidentioJsonParam(params.expressions, 'expressions'),
|
||||
include_private_incidents: params.include_private_incidents,
|
||||
runs_on_incident_modes: parseRequiredIncidentioJsonParam(
|
||||
params.runs_on_incident_modes,
|
||||
'runs_on_incident_modes'
|
||||
),
|
||||
continue_on_step_error: params.continue_on_step_error,
|
||||
runs_on_incidents: params.runs_on_incidents,
|
||||
}
|
||||
|
||||
if (params.state) body.state = params.state
|
||||
if (params.folder) body.folder = params.folder
|
||||
if (params.delay) body.delay = parseIncidentioJsonParam(params.delay, 'delay', undefined)
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
management_meta: data.management_meta,
|
||||
workflow: mapIncidentioWorkflow(data.workflow),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
workflow: {
|
||||
type: 'object',
|
||||
description: 'The updated workflow',
|
||||
properties: INCIDENTIO_WORKFLOW_OUTPUT_PROPERTIES,
|
||||
},
|
||||
management_meta: {
|
||||
type: 'json',
|
||||
description: 'Workflow management metadata',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user