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,78 @@
|
||||
import type { PagerDutyAddNoteParams, PagerDutyAddNoteResponse } from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const addNoteTool: ToolConfig<PagerDutyAddNoteParams, PagerDutyAddNoteResponse> = {
|
||||
id: 'pagerduty_add_note',
|
||||
name: 'PagerDuty Add Note',
|
||||
description: 'Add a note to an existing PagerDuty incident.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
fromEmail: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Email address of a valid PagerDuty user',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident to add the note to',
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Note content text',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pagerduty.com/incidents/${params.incidentId.trim()}/notes`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
From: params.fromEmail,
|
||||
}),
|
||||
body: (params) => ({
|
||||
note: {
|
||||
content: params.content,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const note = data.note ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: note.id ?? null,
|
||||
content: note.content ?? null,
|
||||
createdAt: note.created_at ?? null,
|
||||
userName: note.user?.summary ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Note ID' },
|
||||
content: { type: 'string', description: 'Note content' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
userName: { type: 'string', description: 'Name of the user who created the note' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
import type {
|
||||
PagerDutyCreateIncidentParams,
|
||||
PagerDutyCreateIncidentResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const createIncidentTool: ToolConfig<
|
||||
PagerDutyCreateIncidentParams,
|
||||
PagerDutyCreateIncidentResponse
|
||||
> = {
|
||||
id: 'pagerduty_create_incident',
|
||||
name: 'PagerDuty Create Incident',
|
||||
description: 'Create a new incident in PagerDuty.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
fromEmail: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Email address of a valid PagerDuty user',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Incident title/summary',
|
||||
},
|
||||
serviceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the PagerDuty service',
|
||||
},
|
||||
urgency: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Urgency level (high or low)',
|
||||
},
|
||||
body: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Detailed description of the incident',
|
||||
},
|
||||
escalationPolicyId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Escalation policy ID to assign',
|
||||
},
|
||||
assigneeId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'User ID to assign the incident to',
|
||||
},
|
||||
incidentKey: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'De-duplication key. A subsequent request with the same service and incident key updates the existing open incident instead of creating a new one',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.pagerduty.com/incidents',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
From: params.fromEmail,
|
||||
}),
|
||||
body: (params) => {
|
||||
const incident: Record<string, unknown> = {
|
||||
type: 'incident',
|
||||
title: params.title,
|
||||
service: {
|
||||
id: params.serviceId,
|
||||
type: 'service_reference',
|
||||
},
|
||||
}
|
||||
|
||||
if (params.urgency) incident.urgency = params.urgency
|
||||
if (params.body) {
|
||||
incident.body = {
|
||||
type: 'incident_body',
|
||||
details: params.body,
|
||||
}
|
||||
}
|
||||
if (params.escalationPolicyId) {
|
||||
incident.escalation_policy = {
|
||||
id: params.escalationPolicyId,
|
||||
type: 'escalation_policy_reference',
|
||||
}
|
||||
}
|
||||
if (params.assigneeId) {
|
||||
incident.assignments = [
|
||||
{
|
||||
assignee: {
|
||||
id: params.assigneeId,
|
||||
type: 'user_reference',
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
if (params.incidentKey) incident.incident_key = params.incidentKey
|
||||
|
||||
return { incident }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const inc = data.incident ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: inc.id ?? null,
|
||||
incidentNumber: inc.incident_number ?? null,
|
||||
title: inc.title ?? null,
|
||||
status: inc.status ?? null,
|
||||
urgency: inc.urgency ?? null,
|
||||
createdAt: inc.created_at ?? null,
|
||||
serviceName: inc.service?.summary ?? null,
|
||||
serviceId: inc.service?.id ?? null,
|
||||
htmlUrl: inc.html_url ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Created incident ID' },
|
||||
incidentNumber: { type: 'number', description: 'Incident number' },
|
||||
title: { type: 'string', description: 'Incident title' },
|
||||
status: { type: 'string', description: 'Incident status' },
|
||||
urgency: { type: 'string', description: 'Incident urgency' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
serviceName: { type: 'string', description: 'Service name' },
|
||||
serviceId: { type: 'string', description: 'Service ID' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import type {
|
||||
PagerDutyGetIncidentParams,
|
||||
PagerDutyGetIncidentResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getIncidentTool: ToolConfig<PagerDutyGetIncidentParams, PagerDutyGetIncidentResponse> =
|
||||
{
|
||||
id: 'pagerduty_get_incident',
|
||||
name: 'PagerDuty Get Incident',
|
||||
description: 'Get a single incident from PagerDuty by ID.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident to fetch',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.pagerduty.com/incidents/${params.incidentId.trim()}?include[]=services`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const inc = data.incident ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: inc.id ?? null,
|
||||
incidentNumber: inc.incident_number ?? null,
|
||||
title: inc.title ?? null,
|
||||
status: inc.status ?? null,
|
||||
urgency: inc.urgency ?? null,
|
||||
createdAt: inc.created_at ?? null,
|
||||
updatedAt: inc.updated_at ?? null,
|
||||
resolvedAt: inc.resolved_at ?? null,
|
||||
serviceName: inc.service?.summary ?? null,
|
||||
serviceId: inc.service?.id ?? null,
|
||||
assigneeName: inc.assignments?.[0]?.assignee?.summary ?? null,
|
||||
assigneeId: inc.assignments?.[0]?.assignee?.id ?? null,
|
||||
escalationPolicyName: inc.escalation_policy?.summary ?? null,
|
||||
escalationPolicyId: inc.escalation_policy?.id ?? null,
|
||||
incidentKey: inc.incident_key ?? null,
|
||||
htmlUrl: inc.html_url ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
incidentNumber: { type: 'number', description: 'Incident number' },
|
||||
title: { type: 'string', description: 'Incident title' },
|
||||
status: { type: 'string', description: 'Incident status' },
|
||||
urgency: { type: 'string', description: 'Incident urgency' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
updatedAt: { type: 'string', description: 'Last updated timestamp', optional: true },
|
||||
resolvedAt: { type: 'string', description: 'Resolution timestamp', optional: true },
|
||||
serviceName: { type: 'string', description: 'Service name', optional: true },
|
||||
serviceId: { type: 'string', description: 'Service ID', optional: true },
|
||||
assigneeName: { type: 'string', description: 'Assignee name', optional: true },
|
||||
assigneeId: { type: 'string', description: 'Assignee ID', optional: true },
|
||||
escalationPolicyName: {
|
||||
type: 'string',
|
||||
description: 'Escalation policy name',
|
||||
optional: true,
|
||||
},
|
||||
escalationPolicyId: { type: 'string', description: 'Escalation policy ID', optional: true },
|
||||
incidentKey: { type: 'string', description: 'De-duplication key', optional: true },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import type {
|
||||
PagerDutyGetServiceParams,
|
||||
PagerDutyGetServiceResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getServiceTool: ToolConfig<PagerDutyGetServiceParams, PagerDutyGetServiceResponse> = {
|
||||
id: 'pagerduty_get_service',
|
||||
name: 'PagerDuty Get Service',
|
||||
description: 'Get a single service from PagerDuty by ID.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
serviceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the service to fetch',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.pagerduty.com/services/${params.serviceId.trim()}?include[]=escalation_policies`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const svc = data.service ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: svc.id ?? null,
|
||||
name: svc.name ?? null,
|
||||
description: svc.description ?? null,
|
||||
status: svc.status ?? null,
|
||||
autoResolveTimeout: svc.auto_resolve_timeout ?? null,
|
||||
acknowledgementTimeout: svc.acknowledgement_timeout ?? null,
|
||||
createdAt: svc.created_at ?? null,
|
||||
lastIncidentTimestamp: svc.last_incident_timestamp ?? null,
|
||||
escalationPolicyName: svc.escalation_policy?.summary ?? null,
|
||||
escalationPolicyId: svc.escalation_policy?.id ?? null,
|
||||
htmlUrl: svc.html_url ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Service ID' },
|
||||
name: { type: 'string', description: 'Service name' },
|
||||
description: { type: 'string', description: 'Service description', optional: true },
|
||||
status: { type: 'string', description: 'Service status' },
|
||||
autoResolveTimeout: {
|
||||
type: 'number',
|
||||
description: 'Seconds before an open incident auto-resolves',
|
||||
optional: true,
|
||||
},
|
||||
acknowledgementTimeout: {
|
||||
type: 'number',
|
||||
description: 'Seconds before an acknowledged incident reverts to triggered',
|
||||
optional: true,
|
||||
},
|
||||
createdAt: { type: 'string', description: 'Creation timestamp', optional: true },
|
||||
lastIncidentTimestamp: {
|
||||
type: 'string',
|
||||
description: 'Timestamp of the most recent incident',
|
||||
optional: true,
|
||||
},
|
||||
escalationPolicyName: { type: 'string', description: 'Escalation policy name', optional: true },
|
||||
escalationPolicyId: { type: 'string', description: 'Escalation policy ID', optional: true },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { addNoteTool } from '@/tools/pagerduty/add_note'
|
||||
import { createIncidentTool } from '@/tools/pagerduty/create_incident'
|
||||
import { getIncidentTool } from '@/tools/pagerduty/get_incident'
|
||||
import { getServiceTool } from '@/tools/pagerduty/get_service'
|
||||
import { listEscalationPoliciesTool } from '@/tools/pagerduty/list_escalation_policies'
|
||||
import { listIncidentAlertsTool } from '@/tools/pagerduty/list_incident_alerts'
|
||||
import { listIncidentsTool } from '@/tools/pagerduty/list_incidents'
|
||||
import { listOncallsTool } from '@/tools/pagerduty/list_oncalls'
|
||||
import { listSchedulesTool } from '@/tools/pagerduty/list_schedules'
|
||||
import { listServicesTool } from '@/tools/pagerduty/list_services'
|
||||
import { listUsersTool } from '@/tools/pagerduty/list_users'
|
||||
import { mergeIncidentsTool } from '@/tools/pagerduty/merge_incidents'
|
||||
import { sendEventTool } from '@/tools/pagerduty/send_event'
|
||||
import { snoozeIncidentTool } from '@/tools/pagerduty/snooze_incident'
|
||||
import { updateIncidentTool } from '@/tools/pagerduty/update_incident'
|
||||
|
||||
export const pagerdutyListIncidentsTool = listIncidentsTool
|
||||
export const pagerdutyGetIncidentTool = getIncidentTool
|
||||
export const pagerdutyCreateIncidentTool = createIncidentTool
|
||||
export const pagerdutyUpdateIncidentTool = updateIncidentTool
|
||||
export const pagerdutySnoozeIncidentTool = snoozeIncidentTool
|
||||
export const pagerdutyMergeIncidentsTool = mergeIncidentsTool
|
||||
export const pagerdutyAddNoteTool = addNoteTool
|
||||
export const pagerdutyListIncidentAlertsTool = listIncidentAlertsTool
|
||||
export const pagerdutyListServicesTool = listServicesTool
|
||||
export const pagerdutyGetServiceTool = getServiceTool
|
||||
export const pagerdutyListOncallsTool = listOncallsTool
|
||||
export const pagerdutyListEscalationPoliciesTool = listEscalationPoliciesTool
|
||||
export const pagerdutyListSchedulesTool = listSchedulesTool
|
||||
export const pagerdutyListUsersTool = listUsersTool
|
||||
export const pagerdutySendEventTool = sendEventTool
|
||||
@@ -0,0 +1,119 @@
|
||||
import type {
|
||||
PagerDutyListEscalationPoliciesParams,
|
||||
PagerDutyListEscalationPoliciesResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listEscalationPoliciesTool: ToolConfig<
|
||||
PagerDutyListEscalationPoliciesParams,
|
||||
PagerDutyListEscalationPoliciesResponse
|
||||
> = {
|
||||
id: 'pagerduty_list_escalation_policies',
|
||||
name: 'PagerDuty List Escalation Policies',
|
||||
description: 'List escalation policies from PagerDuty with an optional name filter.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter escalation policies by name',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.query) query.set('query', params.query)
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/escalation_policies${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalationPolicies: (data.escalation_policies ?? []).map((ep: Record<string, unknown>) => ({
|
||||
id: ep.id ?? null,
|
||||
name: ep.name ?? null,
|
||||
description: ep.description ?? null,
|
||||
numLoops: ep.num_loops ?? 0,
|
||||
onCallHandoffNotifications: ep.on_call_handoff_notifications ?? null,
|
||||
htmlUrl: ep.html_url ?? null,
|
||||
})),
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalationPolicies: {
|
||||
type: 'array',
|
||||
description: 'Array of escalation policies',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Escalation policy ID' },
|
||||
name: { type: 'string', description: 'Escalation policy name' },
|
||||
description: { type: 'string', description: 'Escalation policy description' },
|
||||
numLoops: { type: 'number', description: 'Number of times the policy repeats' },
|
||||
onCallHandoffNotifications: {
|
||||
type: 'string',
|
||||
description: 'Handoff notification setting (if_has_services or always)',
|
||||
},
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description:
|
||||
'Total number of matching escalation policies (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import type {
|
||||
PagerDutyListIncidentAlertsParams,
|
||||
PagerDutyListIncidentAlertsResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listIncidentAlertsTool: ToolConfig<
|
||||
PagerDutyListIncidentAlertsParams,
|
||||
PagerDutyListIncidentAlertsResponse
|
||||
> = {
|
||||
id: 'pagerduty_list_incident_alerts',
|
||||
name: 'PagerDuty List Incident Alerts',
|
||||
description: 'List the individual alerts attached to a PagerDuty incident.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident whose alerts to list',
|
||||
},
|
||||
statuses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated statuses to filter (triggered, resolved)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.statuses) {
|
||||
for (const s of params.statuses.split(',')) {
|
||||
query.append('statuses[]', s.trim())
|
||||
}
|
||||
}
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/incidents/${params.incidentId.trim()}/alerts${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
alerts: (data.alerts ?? []).map(
|
||||
(alert: Record<string, unknown> & { service?: Record<string, unknown> }) => ({
|
||||
id: alert.id ?? null,
|
||||
summary: alert.summary ?? null,
|
||||
status: alert.status ?? null,
|
||||
severity: alert.severity ?? null,
|
||||
createdAt: alert.created_at ?? null,
|
||||
alertKey: alert.alert_key ?? null,
|
||||
serviceName: alert.service?.summary ?? null,
|
||||
serviceId: alert.service?.id ?? null,
|
||||
htmlUrl: alert.html_url ?? null,
|
||||
})
|
||||
),
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
alerts: {
|
||||
type: 'array',
|
||||
description: 'Array of alerts attached to the incident',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
status: { type: 'string', description: 'Alert status' },
|
||||
severity: { type: 'string', description: 'Alert severity' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
alertKey: { type: 'string', description: 'De-duplication key' },
|
||||
serviceName: { type: 'string', description: 'Service name' },
|
||||
serviceId: { type: 'string', description: 'Service ID' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description:
|
||||
'Total number of matching alerts (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
import type {
|
||||
PagerDutyListIncidentsParams,
|
||||
PagerDutyListIncidentsResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listIncidentsTool: ToolConfig<
|
||||
PagerDutyListIncidentsParams,
|
||||
PagerDutyListIncidentsResponse
|
||||
> = {
|
||||
id: 'pagerduty_list_incidents',
|
||||
name: 'PagerDuty List Incidents',
|
||||
description: 'List incidents from PagerDuty with optional filters.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
statuses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated statuses to filter (triggered, acknowledged, resolved)',
|
||||
},
|
||||
urgencies: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated urgencies to filter (high, low)',
|
||||
},
|
||||
serviceIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated service IDs to filter',
|
||||
},
|
||||
since: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Start date filter (ISO 8601 format)',
|
||||
},
|
||||
until: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'End date filter (ISO 8601 format)',
|
||||
},
|
||||
sortBy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Sort field (e.g., created_at:desc)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.statuses) {
|
||||
for (const s of params.statuses.split(',')) {
|
||||
query.append('statuses[]', s.trim())
|
||||
}
|
||||
}
|
||||
if (params.urgencies) {
|
||||
for (const u of params.urgencies.split(',')) {
|
||||
query.append('urgencies[]', u.trim())
|
||||
}
|
||||
}
|
||||
if (params.serviceIds) {
|
||||
for (const id of params.serviceIds.split(',')) {
|
||||
query.append('service_ids[]', id.trim())
|
||||
}
|
||||
}
|
||||
if (params.since) query.set('since', params.since)
|
||||
if (params.until) query.set('until', params.until)
|
||||
if (params.sortBy) query.set('sort_by', params.sortBy)
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
query.append('include[]', 'services')
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/incidents${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
incidents: (data.incidents ?? []).map(
|
||||
(
|
||||
inc: Record<string, unknown> & {
|
||||
service?: Record<string, unknown>
|
||||
assignments?: Array<Record<string, unknown> & { assignee?: Record<string, unknown> }>
|
||||
escalation_policy?: Record<string, unknown>
|
||||
}
|
||||
) => ({
|
||||
id: inc.id ?? null,
|
||||
incidentNumber: inc.incident_number ?? null,
|
||||
title: inc.title ?? null,
|
||||
status: inc.status ?? null,
|
||||
urgency: inc.urgency ?? null,
|
||||
createdAt: inc.created_at ?? null,
|
||||
updatedAt: inc.updated_at ?? null,
|
||||
serviceName: inc.service?.summary ?? null,
|
||||
serviceId: inc.service?.id ?? null,
|
||||
assigneeName: inc.assignments?.[0]?.assignee?.summary ?? null,
|
||||
assigneeId: inc.assignments?.[0]?.assignee?.id ?? null,
|
||||
escalationPolicyName: inc.escalation_policy?.summary ?? null,
|
||||
htmlUrl: inc.html_url ?? null,
|
||||
})
|
||||
),
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
incidents: {
|
||||
type: 'array',
|
||||
description: 'Array of incidents',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
incidentNumber: { type: 'number', description: 'Incident number' },
|
||||
title: { type: 'string', description: 'Incident title' },
|
||||
status: { type: 'string', description: 'Incident status' },
|
||||
urgency: { type: 'string', description: 'Incident urgency' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
updatedAt: { type: 'string', description: 'Last updated timestamp' },
|
||||
serviceName: { type: 'string', description: 'Service name' },
|
||||
serviceId: { type: 'string', description: 'Service ID' },
|
||||
assigneeName: { type: 'string', description: 'Assignee name' },
|
||||
assigneeId: { type: 'string', description: 'Assignee ID' },
|
||||
escalationPolicyName: { type: 'string', description: 'Escalation policy name' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description:
|
||||
'Total number of matching incidents (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
import type {
|
||||
PagerDutyListOncallsParams,
|
||||
PagerDutyListOncallsResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listOncallsTool: ToolConfig<PagerDutyListOncallsParams, PagerDutyListOncallsResponse> =
|
||||
{
|
||||
id: 'pagerduty_list_oncalls',
|
||||
name: 'PagerDuty List On-Calls',
|
||||
description: 'List current on-call entries from PagerDuty.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
escalationPolicyIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated escalation policy IDs to filter',
|
||||
},
|
||||
scheduleIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated schedule IDs to filter',
|
||||
},
|
||||
since: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Start time filter (ISO 8601 format)',
|
||||
},
|
||||
until: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'End time filter (ISO 8601 format)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.escalationPolicyIds) {
|
||||
for (const id of params.escalationPolicyIds.split(',')) {
|
||||
query.append('escalation_policy_ids[]', id.trim())
|
||||
}
|
||||
}
|
||||
if (params.scheduleIds) {
|
||||
for (const id of params.scheduleIds.split(',')) {
|
||||
query.append('schedule_ids[]', id.trim())
|
||||
}
|
||||
}
|
||||
if (params.since) query.set('since', params.since)
|
||||
if (params.until) query.set('until', params.until)
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/oncalls${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const oncalls = (data.oncalls ?? []).map(
|
||||
(
|
||||
oc: Record<string, unknown> & {
|
||||
user?: Record<string, unknown>
|
||||
escalation_policy?: Record<string, unknown>
|
||||
schedule?: Record<string, unknown>
|
||||
}
|
||||
) => ({
|
||||
userName: oc.user?.summary ?? null,
|
||||
userId: oc.user?.id ?? null,
|
||||
escalationLevel: oc.escalation_level ?? 0,
|
||||
escalationPolicyName: oc.escalation_policy?.summary ?? null,
|
||||
escalationPolicyId: oc.escalation_policy?.id ?? null,
|
||||
scheduleName: oc.schedule?.summary ?? null,
|
||||
scheduleId: oc.schedule?.id ?? null,
|
||||
start: oc.start ?? null,
|
||||
end: oc.end ?? null,
|
||||
})
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
oncalls,
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
oncalls: {
|
||||
type: 'array',
|
||||
description: 'Array of on-call entries',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
userName: { type: 'string', description: 'On-call user name' },
|
||||
userId: { type: 'string', description: 'On-call user ID' },
|
||||
escalationLevel: { type: 'number', description: 'Escalation level' },
|
||||
escalationPolicyName: { type: 'string', description: 'Escalation policy name' },
|
||||
escalationPolicyId: { type: 'string', description: 'Escalation policy ID' },
|
||||
scheduleName: { type: 'string', description: 'Schedule name' },
|
||||
scheduleId: { type: 'string', description: 'Schedule ID' },
|
||||
start: { type: 'string', description: 'On-call start time' },
|
||||
end: { type: 'string', description: 'On-call end time' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description:
|
||||
'Total number of matching on-call entries (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import type {
|
||||
PagerDutyListSchedulesParams,
|
||||
PagerDutyListSchedulesResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listSchedulesTool: ToolConfig<
|
||||
PagerDutyListSchedulesParams,
|
||||
PagerDutyListSchedulesResponse
|
||||
> = {
|
||||
id: 'pagerduty_list_schedules',
|
||||
name: 'PagerDuty List Schedules',
|
||||
description: 'List on-call schedules from PagerDuty with an optional name filter.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter schedules by name',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.query) query.set('query', params.query)
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/schedules${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedules: (data.schedules ?? []).map((sched: Record<string, unknown>) => ({
|
||||
id: sched.id ?? null,
|
||||
name: sched.name ?? null,
|
||||
description: sched.description ?? null,
|
||||
timeZone: sched.time_zone ?? null,
|
||||
htmlUrl: sched.html_url ?? null,
|
||||
})),
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedules: {
|
||||
type: 'array',
|
||||
description: 'Array of on-call schedules',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Schedule ID' },
|
||||
name: { type: 'string', description: 'Schedule name' },
|
||||
description: { type: 'string', description: 'Schedule description' },
|
||||
timeZone: { type: 'string', description: 'Schedule time zone' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description:
|
||||
'Total number of matching schedules (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
import type {
|
||||
PagerDutyListServicesParams,
|
||||
PagerDutyListServicesResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listServicesTool: ToolConfig<
|
||||
PagerDutyListServicesParams,
|
||||
PagerDutyListServicesResponse
|
||||
> = {
|
||||
id: 'pagerduty_list_services',
|
||||
name: 'PagerDuty List Services',
|
||||
description: 'List services from PagerDuty with optional name filter.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter services by name',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.query) query.set('query', params.query)
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/services${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
services: (data.services ?? []).map(
|
||||
(svc: Record<string, unknown> & { escalation_policy?: Record<string, unknown> }) => ({
|
||||
id: svc.id ?? null,
|
||||
name: svc.name ?? null,
|
||||
description: svc.description ?? null,
|
||||
status: svc.status ?? null,
|
||||
escalationPolicyName: svc.escalation_policy?.summary ?? null,
|
||||
escalationPolicyId: svc.escalation_policy?.id ?? null,
|
||||
createdAt: svc.created_at ?? null,
|
||||
htmlUrl: svc.html_url ?? null,
|
||||
})
|
||||
),
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
services: {
|
||||
type: 'array',
|
||||
description: 'Array of services',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Service ID' },
|
||||
name: { type: 'string', description: 'Service name' },
|
||||
description: { type: 'string', description: 'Service description' },
|
||||
status: { type: 'string', description: 'Service status' },
|
||||
escalationPolicyName: { type: 'string', description: 'Escalation policy name' },
|
||||
escalationPolicyId: { type: 'string', description: 'Escalation policy ID' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description:
|
||||
'Total number of matching services (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import type { PagerDutyListUsersParams, PagerDutyListUsersResponse } from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listUsersTool: ToolConfig<PagerDutyListUsersParams, PagerDutyListUsersResponse> = {
|
||||
id: 'pagerduty_list_users',
|
||||
name: 'PagerDuty List Users',
|
||||
description: 'List users from PagerDuty with an optional name/email filter.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter users by name or email',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results (max 100)',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Offset to start pagination search results',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.query) query.set('query', params.query)
|
||||
if (params.limit) query.set('limit', params.limit)
|
||||
if (params.offset) query.set('offset', params.offset)
|
||||
const qs = query.toString()
|
||||
return `https://api.pagerduty.com/users${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
users: (data.users ?? []).map((u: Record<string, unknown>) => ({
|
||||
id: u.id ?? null,
|
||||
name: u.name ?? null,
|
||||
email: u.email ?? null,
|
||||
role: u.role ?? null,
|
||||
jobTitle: u.job_title ?? null,
|
||||
timeZone: u.time_zone ?? null,
|
||||
htmlUrl: u.html_url ?? null,
|
||||
})),
|
||||
total: data.total ?? null,
|
||||
more: data.more ?? false,
|
||||
offset: data.offset ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
users: {
|
||||
type: 'array',
|
||||
description: 'Array of users',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'User ID' },
|
||||
name: { type: 'string', description: 'User name' },
|
||||
email: { type: 'string', description: 'User email' },
|
||||
role: { type: 'string', description: 'User role' },
|
||||
jobTitle: { type: 'string', description: 'User job title' },
|
||||
timeZone: { type: 'string', description: 'User preferred time zone' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
total: {
|
||||
type: 'number',
|
||||
description: 'Total number of matching users (null unless explicitly requested by PagerDuty)',
|
||||
optional: true,
|
||||
},
|
||||
more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available',
|
||||
},
|
||||
offset: {
|
||||
type: 'number',
|
||||
description: 'Offset used for this page of results',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import type {
|
||||
PagerDutyMergeIncidentsParams,
|
||||
PagerDutyMergeIncidentsResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const mergeIncidentsTool: ToolConfig<
|
||||
PagerDutyMergeIncidentsParams,
|
||||
PagerDutyMergeIncidentsResponse
|
||||
> = {
|
||||
id: 'pagerduty_merge_incidents',
|
||||
name: 'PagerDuty Merge Incidents',
|
||||
description:
|
||||
'Merge one or more source incidents into a target incident. Source incidents are resolved and their alerts move to the target.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
fromEmail: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Email address of a valid PagerDuty user',
|
||||
},
|
||||
targetIncidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident that will absorb the source incidents',
|
||||
},
|
||||
sourceIncidentIds: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated IDs of the incidents to merge into the target incident',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pagerduty.com/incidents/${params.targetIncidentId.trim()}/merge`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
From: params.fromEmail,
|
||||
}),
|
||||
body: (params) => {
|
||||
const sourceIds = params.sourceIncidentIds
|
||||
.split(',')
|
||||
.map((id) => id.trim())
|
||||
.filter((id) => id.length > 0)
|
||||
|
||||
if (sourceIds.length === 0) {
|
||||
throw new Error('sourceIncidentIds must contain at least one non-empty incident ID')
|
||||
}
|
||||
|
||||
return {
|
||||
source_incidents: sourceIds.map((id) => ({
|
||||
id,
|
||||
type: 'incident_reference',
|
||||
})),
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const inc = data.incident ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: inc.id ?? null,
|
||||
incidentNumber: inc.incident_number ?? null,
|
||||
title: inc.title ?? null,
|
||||
status: inc.status ?? null,
|
||||
htmlUrl: inc.html_url ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Target incident ID' },
|
||||
incidentNumber: { type: 'number', description: 'Target incident number' },
|
||||
title: { type: 'string', description: 'Target incident title' },
|
||||
status: { type: 'string', description: 'Target incident status' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import type { PagerDutySendEventParams, PagerDutySendEventResponse } from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const sendEventTool: ToolConfig<PagerDutySendEventParams, PagerDutySendEventResponse> = {
|
||||
id: 'pagerduty_send_event',
|
||||
name: 'PagerDuty Send Event',
|
||||
description:
|
||||
'Send a trigger, acknowledge, or resolve event to PagerDuty Events API v2 using a service integration key. Used to page from monitoring/alerting sources without a PagerDuty user account.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
routingKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'The Events API v2 integration key (routing key) for the target service',
|
||||
},
|
||||
eventAction: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Event action: trigger, acknowledge, or resolve',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Brief summary of the event. Required when eventAction is trigger',
|
||||
},
|
||||
source: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Unique location of the affected system (e.g. hostname). Required when eventAction is trigger',
|
||||
},
|
||||
severity: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Perceived severity: critical, warning, error, or info. Required when eventAction is trigger',
|
||||
},
|
||||
dedupKey: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'De-duplication key identifying the alert. Required when eventAction is acknowledge or resolve; optional on trigger',
|
||||
},
|
||||
component: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Component of the source machine responsible for the event',
|
||||
},
|
||||
group: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Logical grouping of components of a service',
|
||||
},
|
||||
class: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The class/type of the event',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://events.pagerduty.com/v2/enqueue',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
routing_key: params.routingKey,
|
||||
event_action: params.eventAction,
|
||||
}
|
||||
|
||||
if (params.eventAction === 'acknowledge' || params.eventAction === 'resolve') {
|
||||
if (!params.dedupKey) {
|
||||
throw new Error('dedupKey is required when eventAction is acknowledge or resolve')
|
||||
}
|
||||
}
|
||||
|
||||
if (params.dedupKey) body.dedup_key = params.dedupKey
|
||||
|
||||
if (params.eventAction === 'trigger') {
|
||||
if (!params.summary || !params.source || !params.severity) {
|
||||
throw new Error('summary, source, and severity are required when eventAction is trigger')
|
||||
}
|
||||
|
||||
body.payload = {
|
||||
summary: params.summary,
|
||||
source: params.source,
|
||||
severity: params.severity,
|
||||
...(params.component && { component: params.component }),
|
||||
...(params.group && { group: params.group }),
|
||||
...(params.class && { class: params.class }),
|
||||
}
|
||||
}
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.message || `PagerDuty Events API error: ${response.status}`)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
status: data.status ?? null,
|
||||
message: data.message ?? null,
|
||||
dedupKey: data.dedup_key ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
status: { type: 'string', description: 'Result status ("success" if accepted)' },
|
||||
message: { type: 'string', description: 'Description of the result', optional: true },
|
||||
dedupKey: { type: 'string', description: 'De-duplication key for the alert', optional: true },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import type {
|
||||
PagerDutySnoozeIncidentParams,
|
||||
PagerDutySnoozeIncidentResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const snoozeIncidentTool: ToolConfig<
|
||||
PagerDutySnoozeIncidentParams,
|
||||
PagerDutySnoozeIncidentResponse
|
||||
> = {
|
||||
id: 'pagerduty_snooze_incident',
|
||||
name: 'PagerDuty Snooze Incident',
|
||||
description:
|
||||
'Snooze a triggered PagerDuty incident for a number of seconds, after which it returns to triggered.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
fromEmail: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Email address of a valid PagerDuty user',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident to snooze',
|
||||
},
|
||||
duration: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of seconds to snooze the incident for (1 to 604800)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pagerduty.com/incidents/${params.incidentId.trim()}/snooze`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
From: params.fromEmail,
|
||||
}),
|
||||
body: (params) => {
|
||||
const duration = Number(params.duration)
|
||||
if (!Number.isInteger(duration) || duration < 1 || duration > 604800) {
|
||||
throw new Error('duration must be a whole number of seconds between 1 and 604800')
|
||||
}
|
||||
return { duration }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const inc = data.incident ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: inc.id ?? null,
|
||||
incidentNumber: inc.incident_number ?? null,
|
||||
status: inc.status ?? null,
|
||||
htmlUrl: inc.html_url ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
incidentNumber: { type: 'number', description: 'Incident number' },
|
||||
status: { type: 'string', description: 'Incident status after snoozing' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
/**
|
||||
* Base params shared by all PagerDuty endpoints.
|
||||
*/
|
||||
interface PagerDutyBaseParams {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Params that require a From header for write operations.
|
||||
*/
|
||||
interface PagerDutyWriteParams extends PagerDutyBaseParams {
|
||||
fromEmail: string
|
||||
}
|
||||
|
||||
/**
|
||||
* List Incidents params.
|
||||
*/
|
||||
export interface PagerDutyListIncidentsParams extends PagerDutyBaseParams {
|
||||
statuses?: string
|
||||
urgencies?: string
|
||||
serviceIds?: string
|
||||
since?: string
|
||||
until?: string
|
||||
sortBy?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListIncidentsResponse extends ToolResponse {
|
||||
output: {
|
||||
incidents: Array<{
|
||||
id: string
|
||||
incidentNumber: number
|
||||
title: string
|
||||
status: string
|
||||
urgency: string
|
||||
createdAt: string
|
||||
updatedAt: string | null
|
||||
serviceName: string | null
|
||||
serviceId: string | null
|
||||
assigneeName: string | null
|
||||
assigneeId: string | null
|
||||
escalationPolicyName: string | null
|
||||
htmlUrl: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Incident params.
|
||||
*/
|
||||
export interface PagerDutyGetIncidentParams extends PagerDutyBaseParams {
|
||||
incidentId: string
|
||||
}
|
||||
|
||||
export interface PagerDutyGetIncidentResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
incidentNumber: number
|
||||
title: string
|
||||
status: string
|
||||
urgency: string
|
||||
createdAt: string
|
||||
updatedAt: string | null
|
||||
resolvedAt: string | null
|
||||
serviceName: string | null
|
||||
serviceId: string | null
|
||||
assigneeName: string | null
|
||||
assigneeId: string | null
|
||||
escalationPolicyName: string | null
|
||||
escalationPolicyId: string | null
|
||||
incidentKey: string | null
|
||||
htmlUrl: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Incident params.
|
||||
*/
|
||||
export interface PagerDutyCreateIncidentParams extends PagerDutyWriteParams {
|
||||
title: string
|
||||
serviceId: string
|
||||
urgency?: string
|
||||
body?: string
|
||||
escalationPolicyId?: string
|
||||
assigneeId?: string
|
||||
incidentKey?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyCreateIncidentResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
incidentNumber: number
|
||||
title: string
|
||||
status: string
|
||||
urgency: string
|
||||
createdAt: string
|
||||
serviceName: string | null
|
||||
serviceId: string | null
|
||||
htmlUrl: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Incident params.
|
||||
*/
|
||||
export interface PagerDutyUpdateIncidentParams extends PagerDutyWriteParams {
|
||||
incidentId: string
|
||||
status?: string
|
||||
title?: string
|
||||
urgency?: string
|
||||
escalationLevel?: string
|
||||
resolution?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyUpdateIncidentResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
incidentNumber: number
|
||||
title: string
|
||||
status: string
|
||||
urgency: string
|
||||
updatedAt: string | null
|
||||
htmlUrl: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Note to Incident params.
|
||||
*/
|
||||
export interface PagerDutyAddNoteParams extends PagerDutyWriteParams {
|
||||
incidentId: string
|
||||
content: string
|
||||
}
|
||||
|
||||
export interface PagerDutyAddNoteResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
content: string
|
||||
createdAt: string
|
||||
userName: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List Services params.
|
||||
*/
|
||||
export interface PagerDutyListServicesParams extends PagerDutyBaseParams {
|
||||
query?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListServicesResponse extends ToolResponse {
|
||||
output: {
|
||||
services: Array<{
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
status: string
|
||||
escalationPolicyName: string | null
|
||||
escalationPolicyId: string | null
|
||||
createdAt: string
|
||||
htmlUrl: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Service params.
|
||||
*/
|
||||
export interface PagerDutyGetServiceParams extends PagerDutyBaseParams {
|
||||
serviceId: string
|
||||
}
|
||||
|
||||
export interface PagerDutyGetServiceResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
status: string
|
||||
autoResolveTimeout: number | null
|
||||
acknowledgementTimeout: number | null
|
||||
createdAt: string | null
|
||||
lastIncidentTimestamp: string | null
|
||||
escalationPolicyName: string | null
|
||||
escalationPolicyId: string | null
|
||||
htmlUrl: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List On-Calls params.
|
||||
*/
|
||||
export interface PagerDutyListOncallsParams extends PagerDutyBaseParams {
|
||||
escalationPolicyIds?: string
|
||||
scheduleIds?: string
|
||||
since?: string
|
||||
until?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListOncallsResponse extends ToolResponse {
|
||||
output: {
|
||||
oncalls: Array<{
|
||||
userName: string | null
|
||||
userId: string | null
|
||||
escalationLevel: number
|
||||
escalationPolicyName: string | null
|
||||
escalationPolicyId: string | null
|
||||
scheduleName: string | null
|
||||
scheduleId: string | null
|
||||
start: string | null
|
||||
end: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List Escalation Policies params.
|
||||
*/
|
||||
export interface PagerDutyListEscalationPoliciesParams extends PagerDutyBaseParams {
|
||||
query?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListEscalationPoliciesResponse extends ToolResponse {
|
||||
output: {
|
||||
escalationPolicies: Array<{
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
numLoops: number
|
||||
onCallHandoffNotifications: string | null
|
||||
htmlUrl: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List Schedules params.
|
||||
*/
|
||||
export interface PagerDutyListSchedulesParams extends PagerDutyBaseParams {
|
||||
query?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListSchedulesResponse extends ToolResponse {
|
||||
output: {
|
||||
schedules: Array<{
|
||||
id: string
|
||||
name: string
|
||||
description: string | null
|
||||
timeZone: string | null
|
||||
htmlUrl: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List Users params.
|
||||
*/
|
||||
export interface PagerDutyListUsersParams extends PagerDutyBaseParams {
|
||||
query?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListUsersResponse extends ToolResponse {
|
||||
output: {
|
||||
users: Array<{
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
role: string | null
|
||||
jobTitle: string | null
|
||||
timeZone: string | null
|
||||
htmlUrl: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Snooze Incident params.
|
||||
*/
|
||||
export interface PagerDutySnoozeIncidentParams extends PagerDutyWriteParams {
|
||||
incidentId: string
|
||||
duration: string
|
||||
}
|
||||
|
||||
export interface PagerDutySnoozeIncidentResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
incidentNumber: number
|
||||
status: string
|
||||
htmlUrl: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge Incidents params.
|
||||
*/
|
||||
export interface PagerDutyMergeIncidentsParams extends PagerDutyWriteParams {
|
||||
targetIncidentId: string
|
||||
sourceIncidentIds: string
|
||||
}
|
||||
|
||||
export interface PagerDutyMergeIncidentsResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
incidentNumber: number
|
||||
title: string
|
||||
status: string
|
||||
htmlUrl: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List Incident Alerts params.
|
||||
*/
|
||||
export interface PagerDutyListIncidentAlertsParams extends PagerDutyBaseParams {
|
||||
incidentId: string
|
||||
statuses?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PagerDutyListIncidentAlertsResponse extends ToolResponse {
|
||||
output: {
|
||||
alerts: Array<{
|
||||
id: string
|
||||
summary: string | null
|
||||
status: string
|
||||
severity: string | null
|
||||
createdAt: string
|
||||
alertKey: string | null
|
||||
serviceName: string | null
|
||||
serviceId: string | null
|
||||
htmlUrl: string | null
|
||||
}>
|
||||
total: number | null
|
||||
more: boolean
|
||||
offset: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Event (Events API v2) params.
|
||||
*/
|
||||
export interface PagerDutySendEventParams {
|
||||
routingKey: string
|
||||
eventAction: string
|
||||
summary?: string
|
||||
source?: string
|
||||
severity?: string
|
||||
dedupKey?: string
|
||||
component?: string
|
||||
group?: string
|
||||
class?: string
|
||||
}
|
||||
|
||||
export interface PagerDutySendEventResponse extends ToolResponse {
|
||||
output: {
|
||||
status: string
|
||||
message: string | null
|
||||
dedupKey: string | null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
import type {
|
||||
PagerDutyUpdateIncidentParams,
|
||||
PagerDutyUpdateIncidentResponse,
|
||||
} from '@/tools/pagerduty/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const updateIncidentTool: ToolConfig<
|
||||
PagerDutyUpdateIncidentParams,
|
||||
PagerDutyUpdateIncidentResponse
|
||||
> = {
|
||||
id: 'pagerduty_update_incident',
|
||||
name: 'PagerDuty Update Incident',
|
||||
description: 'Update an incident in PagerDuty (acknowledge, resolve, change urgency, etc.).',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PagerDuty REST API Key',
|
||||
},
|
||||
fromEmail: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Email address of a valid PagerDuty user',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the incident to update',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New status (triggered, acknowledged, or resolved)',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New incident title',
|
||||
},
|
||||
urgency: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New urgency (high or low)',
|
||||
},
|
||||
escalationLevel: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Escalation level to escalate to',
|
||||
},
|
||||
resolution: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
"Resolution note added to the incident's log entry. Only used when status is set to resolved",
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pagerduty.com/incidents/${params.incidentId.trim()}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => ({
|
||||
Authorization: `Token token=${params.apiKey}`,
|
||||
Accept: 'application/vnd.pagerduty+json;version=2',
|
||||
'Content-Type': 'application/json',
|
||||
From: params.fromEmail,
|
||||
}),
|
||||
body: (params) => {
|
||||
const incident: Record<string, unknown> = {
|
||||
id: params.incidentId,
|
||||
type: 'incident',
|
||||
}
|
||||
|
||||
if (params.status) incident.status = params.status
|
||||
if (params.title) incident.title = params.title
|
||||
if (params.urgency) incident.urgency = params.urgency
|
||||
if (params.escalationLevel) {
|
||||
incident.escalation_level = Number(params.escalationLevel)
|
||||
}
|
||||
if (params.resolution) {
|
||||
if (params.status !== 'resolved') {
|
||||
throw new Error('resolution can only be set when status is resolved')
|
||||
}
|
||||
incident.resolution = params.resolution
|
||||
}
|
||||
return { incident }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error?.message || `PagerDuty API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const inc = data.incident ?? {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
id: inc.id ?? null,
|
||||
incidentNumber: inc.incident_number ?? null,
|
||||
title: inc.title ?? null,
|
||||
status: inc.status ?? null,
|
||||
urgency: inc.urgency ?? null,
|
||||
updatedAt: inc.updated_at ?? null,
|
||||
htmlUrl: inc.html_url ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: { type: 'string', description: 'Incident ID' },
|
||||
incidentNumber: { type: 'number', description: 'Incident number' },
|
||||
title: { type: 'string', description: 'Incident title' },
|
||||
status: { type: 'string', description: 'Updated status' },
|
||||
urgency: { type: 'string', description: 'Updated urgency' },
|
||||
updatedAt: { type: 'string', description: 'Last updated timestamp' },
|
||||
htmlUrl: { type: 'string', description: 'PagerDuty web URL' },
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user