mirror of
https://github.com/simstudioai/sim.git
synced 2026-08-31 01:11:53 +08:00
feat(rootly): expand Rootly integration from 14 to 27 tools (#3902)
* feat(rootly): expand Rootly integration from 14 to 27 tools Add 13 new tools: delete_incident, get_alert, update_alert, acknowledge_alert, resolve_alert, create_action_item, list_action_items, list_users, list_on_calls, list_schedules, list_escalation_policies, list_causes, list_playbooks. Includes tool files, types, registry, block definition with subBlocks/conditions/params, and docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(rootly): handle 204 No Content response for delete_incident DELETE /v1/incidents/{id} returns 204 with empty body. Avoid calling response.json() on success — return success/message instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(rootly): remove non-TSDoc comments, add empty body to acknowledge_alert Remove all inline section comments from block definition per CLAUDE.md guidelines. Add explicit empty JSON:API body to acknowledge_alert POST to prevent potential 400 from servers expecting a body with Content-Type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(rootly): send empty body on resolve_alert, guard assignedToUserId parse resolve_alert now sends { data: {} } instead of undefined when no optional params are provided, matching the acknowledge_alert fix. create_action_item now validates assignedToUserId is numeric before parseInt to avoid silent NaN coercion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(rootly): extract on-call relationships from JSON:API relationships/included On-call user, schedule, and escalation policy are exposed as JSON:API relationships, not flat attributes. Now extracts IDs from item.relationships and looks up names from the included array. Adds ?include=user,schedule,escalation_policy to the request URL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(rootly): remove last non-TSDoc comment from block definition Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -245,6 +245,7 @@ Create a new alert in Rootly for on-call notification and routing.
|
||||
| --------- | ---- | ----------- |
|
||||
| `alert` | object | The created alert |
|
||||
| ↳ `id` | string | Unique alert ID |
|
||||
| ↳ `shortId` | string | Short alert ID |
|
||||
| ↳ `summary` | string | Alert summary |
|
||||
| ↳ `description` | string | Alert description |
|
||||
| ↳ `source` | string | Alert source |
|
||||
@@ -254,6 +255,8 @@ Create a new alert in Rootly for on-call notification and routing.
|
||||
| ↳ `deduplicationKey` | string | Deduplication key |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| ↳ `startedAt` | string | Start date |
|
||||
| ↳ `endedAt` | string | End date |
|
||||
|
||||
### `rootly_list_alerts`
|
||||
|
||||
@@ -278,6 +281,7 @@ List alerts from Rootly with optional filtering by status, source, and services.
|
||||
| --------- | ---- | ----------- |
|
||||
| `alerts` | array | List of alerts |
|
||||
| ↳ `id` | string | Unique alert ID |
|
||||
| ↳ `shortId` | string | Short alert ID |
|
||||
| ↳ `summary` | string | Alert summary |
|
||||
| ↳ `description` | string | Alert description |
|
||||
| ↳ `source` | string | Alert source |
|
||||
@@ -287,6 +291,8 @@ List alerts from Rootly with optional filtering by status, source, and services.
|
||||
| ↳ `deduplicationKey` | string | Deduplication key |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| ↳ `startedAt` | string | Start date |
|
||||
| ↳ `endedAt` | string | End date |
|
||||
| `totalCount` | number | Total number of alerts returned |
|
||||
|
||||
### `rootly_add_incident_event`
|
||||
@@ -507,4 +513,379 @@ List incident retrospectives (post-mortems) from Rootly.
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of retrospectives returned |
|
||||
|
||||
### `rootly_delete_incident`
|
||||
|
||||
Delete an incident by ID from Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `incidentId` | string | Yes | The ID of the incident to delete |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `success` | boolean | Whether the deletion succeeded |
|
||||
| `message` | string | Result message |
|
||||
|
||||
### `rootly_get_alert`
|
||||
|
||||
Retrieve a single alert by ID from Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `alertId` | string | Yes | The ID of the alert to retrieve |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `alert` | object | The alert details |
|
||||
| ↳ `id` | string | Unique alert ID |
|
||||
| ↳ `shortId` | string | Short alert ID |
|
||||
| ↳ `summary` | string | Alert summary |
|
||||
| ↳ `description` | string | Alert description |
|
||||
| ↳ `source` | string | Alert source |
|
||||
| ↳ `status` | string | Alert status |
|
||||
| ↳ `externalId` | string | External ID |
|
||||
| ↳ `externalUrl` | string | External URL |
|
||||
| ↳ `deduplicationKey` | string | Deduplication key |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| ↳ `startedAt` | string | Start date |
|
||||
| ↳ `endedAt` | string | End date |
|
||||
|
||||
### `rootly_update_alert`
|
||||
|
||||
Update an existing alert in Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `alertId` | string | Yes | The ID of the alert to update |
|
||||
| `summary` | string | No | Updated alert summary |
|
||||
| `description` | string | No | Updated alert description |
|
||||
| `source` | string | No | Updated alert source |
|
||||
| `serviceIds` | string | No | Comma-separated service IDs to attach |
|
||||
| `groupIds` | string | No | Comma-separated team/group IDs to attach |
|
||||
| `environmentIds` | string | No | Comma-separated environment IDs to attach |
|
||||
| `externalId` | string | No | Updated external ID |
|
||||
| `externalUrl` | string | No | Updated external URL |
|
||||
| `deduplicationKey` | string | No | Updated deduplication key |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `alert` | object | The updated alert |
|
||||
| ↳ `id` | string | Unique alert ID |
|
||||
| ↳ `shortId` | string | Short alert ID |
|
||||
| ↳ `summary` | string | Alert summary |
|
||||
| ↳ `description` | string | Alert description |
|
||||
| ↳ `source` | string | Alert source |
|
||||
| ↳ `status` | string | Alert status |
|
||||
| ↳ `externalId` | string | External ID |
|
||||
| ↳ `externalUrl` | string | External URL |
|
||||
| ↳ `deduplicationKey` | string | Deduplication key |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| ↳ `startedAt` | string | Start date |
|
||||
| ↳ `endedAt` | string | End date |
|
||||
|
||||
### `rootly_acknowledge_alert`
|
||||
|
||||
Acknowledge an alert in Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `alertId` | string | Yes | The ID of the alert to acknowledge |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `alert` | object | The acknowledged alert |
|
||||
| ↳ `id` | string | Unique alert ID |
|
||||
| ↳ `shortId` | string | Short alert ID |
|
||||
| ↳ `summary` | string | Alert summary |
|
||||
| ↳ `description` | string | Alert description |
|
||||
| ↳ `source` | string | Alert source |
|
||||
| ↳ `status` | string | Alert status |
|
||||
| ↳ `externalId` | string | External ID |
|
||||
| ↳ `externalUrl` | string | External URL |
|
||||
| ↳ `deduplicationKey` | string | Deduplication key |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| ↳ `startedAt` | string | Start date |
|
||||
| ↳ `endedAt` | string | End date |
|
||||
|
||||
### `rootly_resolve_alert`
|
||||
|
||||
Resolve an alert in Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `alertId` | string | Yes | The ID of the alert to resolve |
|
||||
| `resolutionMessage` | string | No | Message describing how the alert was resolved |
|
||||
| `resolveRelatedIncidents` | boolean | No | Whether to also resolve related incidents |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `alert` | object | The resolved alert |
|
||||
| ↳ `id` | string | Unique alert ID |
|
||||
| ↳ `shortId` | string | Short alert ID |
|
||||
| ↳ `summary` | string | Alert summary |
|
||||
| ↳ `description` | string | Alert description |
|
||||
| ↳ `source` | string | Alert source |
|
||||
| ↳ `status` | string | Alert status |
|
||||
| ↳ `externalId` | string | External ID |
|
||||
| ↳ `externalUrl` | string | External URL |
|
||||
| ↳ `deduplicationKey` | string | Deduplication key |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| ↳ `startedAt` | string | Start date |
|
||||
| ↳ `endedAt` | string | End date |
|
||||
|
||||
### `rootly_create_action_item`
|
||||
|
||||
Create a new action item for an incident in Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `incidentId` | string | Yes | The ID of the incident to add the action item to |
|
||||
| `summary` | string | Yes | The title of the action item |
|
||||
| `description` | string | No | A detailed description of the action item |
|
||||
| `kind` | string | No | The kind of action item \(task, follow_up\) |
|
||||
| `priority` | string | No | Priority level \(high, medium, low\) |
|
||||
| `status` | string | No | Action item status \(open, in_progress, cancelled, done\) |
|
||||
| `assignedToUserId` | string | No | The user ID to assign the action item to |
|
||||
| `dueDate` | string | No | Due date for the action item |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `actionItem` | object | The created action item |
|
||||
| ↳ `id` | string | Unique action item ID |
|
||||
| ↳ `summary` | string | Action item title |
|
||||
| ↳ `description` | string | Action item description |
|
||||
| ↳ `kind` | string | Action item kind \(task, follow_up\) |
|
||||
| ↳ `priority` | string | Priority level |
|
||||
| ↳ `status` | string | Action item status |
|
||||
| ↳ `dueDate` | string | Due date |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
|
||||
### `rootly_list_action_items`
|
||||
|
||||
List action items for an incident in Rootly.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `incidentId` | string | Yes | The ID of the incident to list action items for |
|
||||
| `pageSize` | number | No | Number of items per page \(default: 20\) |
|
||||
| `pageNumber` | number | No | Page number for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `actionItems` | array | List of action items |
|
||||
| ↳ `id` | string | Unique action item ID |
|
||||
| ↳ `summary` | string | Action item title |
|
||||
| ↳ `description` | string | Action item description |
|
||||
| ↳ `kind` | string | Action item kind \(task, follow_up\) |
|
||||
| ↳ `priority` | string | Priority level |
|
||||
| ↳ `status` | string | Action item status |
|
||||
| ↳ `dueDate` | string | Due date |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of action items returned |
|
||||
|
||||
### `rootly_list_users`
|
||||
|
||||
List users from Rootly with optional search and email filtering.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `search` | string | No | Search term to filter users |
|
||||
| `email` | string | No | Filter users by email address |
|
||||
| `pageSize` | number | No | Number of items per page \(default: 20\) |
|
||||
| `pageNumber` | number | No | Page number for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `users` | array | List of users |
|
||||
| ↳ `id` | string | Unique user ID |
|
||||
| ↳ `email` | string | User email address |
|
||||
| ↳ `firstName` | string | User first name |
|
||||
| ↳ `lastName` | string | User last name |
|
||||
| ↳ `fullName` | string | User full name |
|
||||
| ↳ `timeZone` | string | User time zone |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of users returned |
|
||||
|
||||
### `rootly_list_on_calls`
|
||||
|
||||
List current on-call entries from Rootly with optional filtering.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `scheduleIds` | string | No | Comma-separated schedule IDs to filter by |
|
||||
| `escalationPolicyIds` | string | No | Comma-separated escalation policy IDs to filter by |
|
||||
| `userIds` | string | No | Comma-separated user IDs to filter by |
|
||||
| `serviceIds` | string | No | Comma-separated service IDs to filter by |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `onCalls` | array | List of on-call entries |
|
||||
| ↳ `id` | string | Unique on-call entry ID |
|
||||
| ↳ `userId` | string | ID of the on-call user |
|
||||
| ↳ `userName` | string | Name of the on-call user |
|
||||
| ↳ `scheduleId` | string | ID of the associated schedule |
|
||||
| ↳ `scheduleName` | string | Name of the associated schedule |
|
||||
| ↳ `escalationPolicyId` | string | ID of the associated escalation policy |
|
||||
| ↳ `startTime` | string | On-call start time |
|
||||
| ↳ `endTime` | string | On-call end time |
|
||||
| `totalCount` | number | Total number of on-call entries returned |
|
||||
|
||||
### `rootly_list_schedules`
|
||||
|
||||
List on-call schedules from Rootly with optional search filtering.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `search` | string | No | Search term to filter schedules |
|
||||
| `pageSize` | number | No | Number of items per page \(default: 20\) |
|
||||
| `pageNumber` | number | No | Page number for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `schedules` | array | List of schedules |
|
||||
| ↳ `id` | string | Unique schedule ID |
|
||||
| ↳ `name` | string | Schedule name |
|
||||
| ↳ `description` | string | Schedule description |
|
||||
| ↳ `allTimeCoverage` | boolean | Whether schedule provides 24/7 coverage |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of schedules returned |
|
||||
|
||||
### `rootly_list_escalation_policies`
|
||||
|
||||
List escalation policies from Rootly with optional search filtering.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `search` | string | No | Search term to filter escalation policies |
|
||||
| `pageSize` | number | No | Number of items per page \(default: 20\) |
|
||||
| `pageNumber` | number | No | Page number for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `escalationPolicies` | array | List of escalation policies |
|
||||
| ↳ `id` | string | Unique escalation policy ID |
|
||||
| ↳ `name` | string | Escalation policy name |
|
||||
| ↳ `description` | string | Escalation policy description |
|
||||
| ↳ `repeatCount` | number | Number of times to repeat escalation |
|
||||
| ↳ `groupIds` | array | Associated group IDs |
|
||||
| ↳ `serviceIds` | array | Associated service IDs |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of escalation policies returned |
|
||||
|
||||
### `rootly_list_causes`
|
||||
|
||||
List causes from Rootly with optional search filtering.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `search` | string | No | Search term to filter causes |
|
||||
| `pageSize` | number | No | Number of items per page \(default: 20\) |
|
||||
| `pageNumber` | number | No | Page number for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `causes` | array | List of causes |
|
||||
| ↳ `id` | string | Unique cause ID |
|
||||
| ↳ `name` | string | Cause name |
|
||||
| ↳ `slug` | string | Cause slug |
|
||||
| ↳ `description` | string | Cause description |
|
||||
| ↳ `position` | number | Cause position |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of causes returned |
|
||||
|
||||
### `rootly_list_playbooks`
|
||||
|
||||
List playbooks from Rootly with pagination support.
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `apiKey` | string | Yes | Rootly API key |
|
||||
| `pageSize` | number | No | Number of items per page \(default: 20\) |
|
||||
| `pageNumber` | number | No | Page number for pagination |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `playbooks` | array | List of playbooks |
|
||||
| ↳ `id` | string | Unique playbook ID |
|
||||
| ↳ `title` | string | Playbook title |
|
||||
| ↳ `summary` | string | Playbook summary |
|
||||
| ↳ `externalUrl` | string | External URL |
|
||||
| ↳ `createdAt` | string | Creation date |
|
||||
| ↳ `updatedAt` | string | Last update date |
|
||||
| `totalCount` | number | Total number of playbooks returned |
|
||||
|
||||
|
||||
|
||||
@@ -9820,9 +9820,61 @@
|
||||
{
|
||||
"name": "List Retrospectives",
|
||||
"description": "List incident retrospectives (post-mortems) from Rootly."
|
||||
},
|
||||
{
|
||||
"name": "Delete Incident",
|
||||
"description": "Delete an incident by ID from Rootly."
|
||||
},
|
||||
{
|
||||
"name": "Get Alert",
|
||||
"description": "Retrieve a single alert by ID from Rootly."
|
||||
},
|
||||
{
|
||||
"name": "Update Alert",
|
||||
"description": "Update an existing alert in Rootly."
|
||||
},
|
||||
{
|
||||
"name": "Acknowledge Alert",
|
||||
"description": "Acknowledge an alert in Rootly."
|
||||
},
|
||||
{
|
||||
"name": "Resolve Alert",
|
||||
"description": "Resolve an alert in Rootly."
|
||||
},
|
||||
{
|
||||
"name": "Create Action Item",
|
||||
"description": "Create a new action item for an incident in Rootly."
|
||||
},
|
||||
{
|
||||
"name": "List Action Items",
|
||||
"description": "List action items for an incident in Rootly."
|
||||
},
|
||||
{
|
||||
"name": "List Users",
|
||||
"description": "List users from Rootly with optional search and email filtering."
|
||||
},
|
||||
{
|
||||
"name": "List On-Calls",
|
||||
"description": "List current on-call entries from Rootly with optional filtering."
|
||||
},
|
||||
{
|
||||
"name": "List Schedules",
|
||||
"description": "List on-call schedules from Rootly with optional search filtering."
|
||||
},
|
||||
{
|
||||
"name": "List Escalation Policies",
|
||||
"description": "List escalation policies from Rootly with optional search filtering."
|
||||
},
|
||||
{
|
||||
"name": "List Causes",
|
||||
"description": "List causes from Rootly with optional search filtering."
|
||||
},
|
||||
{
|
||||
"name": "List Playbooks",
|
||||
"description": "List playbooks from Rootly with pagination support."
|
||||
}
|
||||
],
|
||||
"operationCount": 14,
|
||||
"operationCount": 27,
|
||||
"triggers": [],
|
||||
"triggerCount": 0,
|
||||
"authType": "api-key",
|
||||
|
||||
@@ -36,11 +36,23 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
{ label: 'List Incident Types', id: 'rootly_list_incident_types' },
|
||||
{ label: 'List Functionalities', id: 'rootly_list_functionalities' },
|
||||
{ label: 'List Retrospectives', id: 'rootly_list_retrospectives' },
|
||||
{ label: 'Delete Incident', id: 'rootly_delete_incident' },
|
||||
{ label: 'Get Alert', id: 'rootly_get_alert' },
|
||||
{ label: 'Update Alert', id: 'rootly_update_alert' },
|
||||
{ label: 'Acknowledge Alert', id: 'rootly_acknowledge_alert' },
|
||||
{ label: 'Resolve Alert', id: 'rootly_resolve_alert' },
|
||||
{ label: 'Create Action Item', id: 'rootly_create_action_item' },
|
||||
{ label: 'List Action Items', id: 'rootly_list_action_items' },
|
||||
{ label: 'List Users', id: 'rootly_list_users' },
|
||||
{ label: 'List On-Calls', id: 'rootly_list_on_calls' },
|
||||
{ label: 'List Schedules', id: 'rootly_list_schedules' },
|
||||
{ label: 'List Escalation Policies', id: 'rootly_list_escalation_policies' },
|
||||
{ label: 'List Causes', id: 'rootly_list_causes' },
|
||||
{ label: 'List Playbooks', id: 'rootly_list_playbooks' },
|
||||
],
|
||||
value: () => 'rootly_create_incident',
|
||||
},
|
||||
|
||||
// Create Incident fields
|
||||
{
|
||||
id: 'title',
|
||||
title: 'Title',
|
||||
@@ -170,7 +182,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// Get Incident fields
|
||||
{
|
||||
id: 'getIncidentId',
|
||||
title: 'Incident ID',
|
||||
@@ -180,7 +191,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
required: { field: 'operation', value: 'rootly_get_incident' },
|
||||
},
|
||||
|
||||
// Update Incident fields
|
||||
{
|
||||
id: 'updateIncidentId',
|
||||
title: 'Incident ID',
|
||||
@@ -341,7 +351,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Incidents fields
|
||||
{
|
||||
id: 'listIncidentsStatus',
|
||||
title: 'Status Filter',
|
||||
@@ -434,7 +443,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// Create Alert fields
|
||||
{
|
||||
id: 'alertSummary',
|
||||
title: 'Summary',
|
||||
@@ -520,7 +528,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Alerts fields
|
||||
{
|
||||
id: 'listAlertsStatus',
|
||||
title: 'Status Filter',
|
||||
@@ -585,7 +592,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// Add Incident Event fields
|
||||
{
|
||||
id: 'eventIncidentId',
|
||||
title: 'Incident ID',
|
||||
@@ -616,7 +622,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Services fields
|
||||
{
|
||||
id: 'servicesSearch',
|
||||
title: 'Search',
|
||||
@@ -641,7 +646,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Severities fields
|
||||
{
|
||||
id: 'severitiesSearch',
|
||||
title: 'Search',
|
||||
@@ -666,7 +670,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Teams fields
|
||||
{
|
||||
id: 'teamsSearch',
|
||||
title: 'Search',
|
||||
@@ -691,7 +694,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Environments fields
|
||||
{
|
||||
id: 'environmentsSearch',
|
||||
title: 'Search',
|
||||
@@ -716,7 +718,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Incident Types fields
|
||||
{
|
||||
id: 'incidentTypesSearch',
|
||||
title: 'Name Filter',
|
||||
@@ -741,7 +742,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Functionalities fields
|
||||
{
|
||||
id: 'functionalitiesSearch',
|
||||
title: 'Search',
|
||||
@@ -766,7 +766,6 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// List Retrospectives fields
|
||||
{
|
||||
id: 'retrospectivesStatus',
|
||||
title: 'Status Filter',
|
||||
@@ -803,7 +802,404 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
// API Key (common)
|
||||
{
|
||||
id: 'deleteIncidentId',
|
||||
title: 'Incident ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the incident to delete',
|
||||
condition: { field: 'operation', value: 'rootly_delete_incident' },
|
||||
required: { field: 'operation', value: 'rootly_delete_incident' },
|
||||
},
|
||||
|
||||
{
|
||||
id: 'getAlertId',
|
||||
title: 'Alert ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the alert to retrieve',
|
||||
condition: { field: 'operation', value: 'rootly_get_alert' },
|
||||
required: { field: 'operation', value: 'rootly_get_alert' },
|
||||
},
|
||||
|
||||
{
|
||||
id: 'updateAlertId',
|
||||
title: 'Alert ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the alert to update',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
required: { field: 'operation', value: 'rootly_update_alert' },
|
||||
},
|
||||
{
|
||||
id: 'updateAlertSummary',
|
||||
title: 'Summary',
|
||||
type: 'short-input',
|
||||
placeholder: 'Updated alert summary',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
},
|
||||
{
|
||||
id: 'updateAlertDescription',
|
||||
title: 'Description',
|
||||
type: 'long-input',
|
||||
placeholder: 'Updated alert description',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
},
|
||||
{
|
||||
id: 'updateAlertSource',
|
||||
title: 'Source',
|
||||
type: 'short-input',
|
||||
placeholder: 'Alert source (e.g., api, datadog)',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'updateAlertServiceIds',
|
||||
title: 'Service IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated service IDs',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'updateAlertGroupIds',
|
||||
title: 'Team IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated team/group IDs',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'updateAlertEnvironmentIds',
|
||||
title: 'Environment IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated environment IDs',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'updateAlertExternalId',
|
||||
title: 'External ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'External alert ID',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'updateAlertExternalUrl',
|
||||
title: 'External URL',
|
||||
type: 'short-input',
|
||||
placeholder: 'Link to external source',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'updateAlertDeduplicationKey',
|
||||
title: 'Deduplication Key',
|
||||
type: 'short-input',
|
||||
placeholder: 'Key to deduplicate alerts',
|
||||
condition: { field: 'operation', value: 'rootly_update_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'ackAlertId',
|
||||
title: 'Alert ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the alert to acknowledge',
|
||||
condition: { field: 'operation', value: 'rootly_acknowledge_alert' },
|
||||
required: { field: 'operation', value: 'rootly_acknowledge_alert' },
|
||||
},
|
||||
|
||||
{
|
||||
id: 'resolveAlertId',
|
||||
title: 'Alert ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the alert to resolve',
|
||||
condition: { field: 'operation', value: 'rootly_resolve_alert' },
|
||||
required: { field: 'operation', value: 'rootly_resolve_alert' },
|
||||
},
|
||||
{
|
||||
id: 'resolveResolutionMessage',
|
||||
title: 'Resolution Message',
|
||||
type: 'long-input',
|
||||
placeholder: 'How was the alert resolved?',
|
||||
condition: { field: 'operation', value: 'rootly_resolve_alert' },
|
||||
},
|
||||
{
|
||||
id: 'resolveRelatedIncidents',
|
||||
title: 'Resolve Related Incidents',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'No', id: '' },
|
||||
{ label: 'Yes', id: 'true' },
|
||||
],
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'rootly_resolve_alert' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'actionItemIncidentId',
|
||||
title: 'Incident ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the incident',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
required: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
},
|
||||
{
|
||||
id: 'actionItemSummary',
|
||||
title: 'Summary',
|
||||
type: 'short-input',
|
||||
placeholder: 'Action item title',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
required: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
},
|
||||
{
|
||||
id: 'actionItemDescription',
|
||||
title: 'Description',
|
||||
type: 'long-input',
|
||||
placeholder: 'Describe the action item',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
},
|
||||
{
|
||||
id: 'actionItemKind',
|
||||
title: 'Kind',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Default', id: '' },
|
||||
{ label: 'Task', id: 'task' },
|
||||
{ label: 'Follow Up', id: 'follow_up' },
|
||||
],
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
},
|
||||
{
|
||||
id: 'actionItemPriority',
|
||||
title: 'Priority',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Default', id: '' },
|
||||
{ label: 'High', id: 'high' },
|
||||
{ label: 'Medium', id: 'medium' },
|
||||
{ label: 'Low', id: 'low' },
|
||||
],
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
},
|
||||
{
|
||||
id: 'actionItemStatus',
|
||||
title: 'Status',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Default', id: '' },
|
||||
{ label: 'Open', id: 'open' },
|
||||
{ label: 'In Progress', id: 'in_progress' },
|
||||
{ label: 'Cancelled', id: 'cancelled' },
|
||||
{ label: 'Done', id: 'done' },
|
||||
],
|
||||
value: () => '',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'actionItemAssignedToUserId',
|
||||
title: 'Assigned To User ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'User ID to assign (use List Users to find IDs)',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'actionItemDueDate',
|
||||
title: 'Due Date',
|
||||
type: 'short-input',
|
||||
placeholder: 'YYYY-MM-DD',
|
||||
condition: { field: 'operation', value: 'rootly_create_action_item' },
|
||||
mode: 'advanced',
|
||||
wandConfig: {
|
||||
enabled: true,
|
||||
prompt:
|
||||
'Generate a date in YYYY-MM-DD format for the requested due date. Return ONLY the date string - no explanations, no extra text.',
|
||||
placeholder: 'Describe the due date (e.g., "next Friday", "in 2 weeks")...',
|
||||
generationType: 'timestamp',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
id: 'listActionItemsIncidentId',
|
||||
title: 'Incident ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'The ID of the incident',
|
||||
condition: { field: 'operation', value: 'rootly_list_action_items' },
|
||||
required: { field: 'operation', value: 'rootly_list_action_items' },
|
||||
},
|
||||
{
|
||||
id: 'listActionItemsPageSize',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '20',
|
||||
condition: { field: 'operation', value: 'rootly_list_action_items' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'listActionItemsPageNumber',
|
||||
title: 'Page Number',
|
||||
type: 'short-input',
|
||||
placeholder: '1',
|
||||
condition: { field: 'operation', value: 'rootly_list_action_items' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'usersSearch',
|
||||
title: 'Search',
|
||||
type: 'short-input',
|
||||
placeholder: 'Search users...',
|
||||
condition: { field: 'operation', value: 'rootly_list_users' },
|
||||
},
|
||||
{
|
||||
id: 'usersEmail',
|
||||
title: 'Email Filter',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by email address',
|
||||
condition: { field: 'operation', value: 'rootly_list_users' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'usersPageSize',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '20',
|
||||
condition: { field: 'operation', value: 'rootly_list_users' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'usersPageNumber',
|
||||
title: 'Page Number',
|
||||
type: 'short-input',
|
||||
placeholder: '1',
|
||||
condition: { field: 'operation', value: 'rootly_list_users' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'onCallsScheduleIds',
|
||||
title: 'Schedule IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated schedule IDs',
|
||||
condition: { field: 'operation', value: 'rootly_list_on_calls' },
|
||||
},
|
||||
{
|
||||
id: 'onCallsEscalationPolicyIds',
|
||||
title: 'Escalation Policy IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated escalation policy IDs',
|
||||
condition: { field: 'operation', value: 'rootly_list_on_calls' },
|
||||
},
|
||||
{
|
||||
id: 'onCallsUserIds',
|
||||
title: 'User IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated user IDs',
|
||||
condition: { field: 'operation', value: 'rootly_list_on_calls' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'onCallsServiceIds',
|
||||
title: 'Service IDs',
|
||||
type: 'short-input',
|
||||
placeholder: 'Comma-separated service IDs',
|
||||
condition: { field: 'operation', value: 'rootly_list_on_calls' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'schedulesSearch',
|
||||
title: 'Search',
|
||||
type: 'short-input',
|
||||
placeholder: 'Search schedules...',
|
||||
condition: { field: 'operation', value: 'rootly_list_schedules' },
|
||||
},
|
||||
{
|
||||
id: 'schedulesPageSize',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '20',
|
||||
condition: { field: 'operation', value: 'rootly_list_schedules' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'schedulesPageNumber',
|
||||
title: 'Page Number',
|
||||
type: 'short-input',
|
||||
placeholder: '1',
|
||||
condition: { field: 'operation', value: 'rootly_list_schedules' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'escalationPoliciesSearch',
|
||||
title: 'Search',
|
||||
type: 'short-input',
|
||||
placeholder: 'Search escalation policies...',
|
||||
condition: { field: 'operation', value: 'rootly_list_escalation_policies' },
|
||||
},
|
||||
{
|
||||
id: 'escalationPoliciesPageSize',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '20',
|
||||
condition: { field: 'operation', value: 'rootly_list_escalation_policies' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'escalationPoliciesPageNumber',
|
||||
title: 'Page Number',
|
||||
type: 'short-input',
|
||||
placeholder: '1',
|
||||
condition: { field: 'operation', value: 'rootly_list_escalation_policies' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'causesSearch',
|
||||
title: 'Search',
|
||||
type: 'short-input',
|
||||
placeholder: 'Search causes...',
|
||||
condition: { field: 'operation', value: 'rootly_list_causes' },
|
||||
},
|
||||
{
|
||||
id: 'causesPageSize',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '20',
|
||||
condition: { field: 'operation', value: 'rootly_list_causes' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'causesPageNumber',
|
||||
title: 'Page Number',
|
||||
type: 'short-input',
|
||||
placeholder: '1',
|
||||
condition: { field: 'operation', value: 'rootly_list_causes' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'playbooksPageSize',
|
||||
title: 'Page Size',
|
||||
type: 'short-input',
|
||||
placeholder: '20',
|
||||
condition: { field: 'operation', value: 'rootly_list_playbooks' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
{
|
||||
id: 'playbooksPageNumber',
|
||||
title: 'Page Number',
|
||||
type: 'short-input',
|
||||
placeholder: '1',
|
||||
condition: { field: 'operation', value: 'rootly_list_playbooks' },
|
||||
mode: 'advanced',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'apiKey',
|
||||
title: 'API Key',
|
||||
@@ -829,6 +1225,19 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
'rootly_list_incident_types',
|
||||
'rootly_list_functionalities',
|
||||
'rootly_list_retrospectives',
|
||||
'rootly_delete_incident',
|
||||
'rootly_get_alert',
|
||||
'rootly_update_alert',
|
||||
'rootly_acknowledge_alert',
|
||||
'rootly_resolve_alert',
|
||||
'rootly_create_action_item',
|
||||
'rootly_list_action_items',
|
||||
'rootly_list_users',
|
||||
'rootly_list_on_calls',
|
||||
'rootly_list_schedules',
|
||||
'rootly_list_escalation_policies',
|
||||
'rootly_list_causes',
|
||||
'rootly_list_playbooks',
|
||||
],
|
||||
config: {
|
||||
tool: (params) => params.operation,
|
||||
@@ -1012,6 +1421,131 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
: undefined,
|
||||
}
|
||||
|
||||
case 'rootly_delete_incident':
|
||||
return {
|
||||
...baseParams,
|
||||
incidentId: params.deleteIncidentId,
|
||||
}
|
||||
|
||||
case 'rootly_get_alert':
|
||||
return {
|
||||
...baseParams,
|
||||
alertId: params.getAlertId,
|
||||
}
|
||||
|
||||
case 'rootly_update_alert':
|
||||
return {
|
||||
...baseParams,
|
||||
alertId: params.updateAlertId,
|
||||
summary: params.updateAlertSummary,
|
||||
description: params.updateAlertDescription,
|
||||
source: params.updateAlertSource,
|
||||
serviceIds: params.updateAlertServiceIds,
|
||||
groupIds: params.updateAlertGroupIds,
|
||||
environmentIds: params.updateAlertEnvironmentIds,
|
||||
externalId: params.updateAlertExternalId,
|
||||
externalUrl: params.updateAlertExternalUrl,
|
||||
deduplicationKey: params.updateAlertDeduplicationKey,
|
||||
}
|
||||
|
||||
case 'rootly_acknowledge_alert':
|
||||
return {
|
||||
...baseParams,
|
||||
alertId: params.ackAlertId,
|
||||
}
|
||||
|
||||
case 'rootly_resolve_alert':
|
||||
return {
|
||||
...baseParams,
|
||||
alertId: params.resolveAlertId,
|
||||
resolutionMessage: params.resolveResolutionMessage,
|
||||
resolveRelatedIncidents: params.resolveRelatedIncidents
|
||||
? params.resolveRelatedIncidents === 'true'
|
||||
: undefined,
|
||||
}
|
||||
|
||||
case 'rootly_create_action_item':
|
||||
return {
|
||||
...baseParams,
|
||||
incidentId: params.actionItemIncidentId,
|
||||
summary: params.actionItemSummary,
|
||||
description: params.actionItemDescription,
|
||||
kind: params.actionItemKind,
|
||||
priority: params.actionItemPriority,
|
||||
status: params.actionItemStatus,
|
||||
assignedToUserId: params.actionItemAssignedToUserId,
|
||||
dueDate: params.actionItemDueDate,
|
||||
}
|
||||
|
||||
case 'rootly_list_action_items':
|
||||
return {
|
||||
...baseParams,
|
||||
incidentId: params.listActionItemsIncidentId,
|
||||
pageSize: params.listActionItemsPageSize
|
||||
? Number(params.listActionItemsPageSize)
|
||||
: undefined,
|
||||
pageNumber: params.listActionItemsPageNumber
|
||||
? Number(params.listActionItemsPageNumber)
|
||||
: undefined,
|
||||
}
|
||||
|
||||
case 'rootly_list_users':
|
||||
return {
|
||||
...baseParams,
|
||||
search: params.usersSearch,
|
||||
email: params.usersEmail,
|
||||
pageSize: params.usersPageSize ? Number(params.usersPageSize) : undefined,
|
||||
pageNumber: params.usersPageNumber ? Number(params.usersPageNumber) : undefined,
|
||||
}
|
||||
|
||||
case 'rootly_list_on_calls':
|
||||
return {
|
||||
...baseParams,
|
||||
scheduleIds: params.onCallsScheduleIds,
|
||||
escalationPolicyIds: params.onCallsEscalationPolicyIds,
|
||||
userIds: params.onCallsUserIds,
|
||||
serviceIds: params.onCallsServiceIds,
|
||||
}
|
||||
|
||||
case 'rootly_list_schedules':
|
||||
return {
|
||||
...baseParams,
|
||||
search: params.schedulesSearch,
|
||||
pageSize: params.schedulesPageSize ? Number(params.schedulesPageSize) : undefined,
|
||||
pageNumber: params.schedulesPageNumber
|
||||
? Number(params.schedulesPageNumber)
|
||||
: undefined,
|
||||
}
|
||||
|
||||
case 'rootly_list_escalation_policies':
|
||||
return {
|
||||
...baseParams,
|
||||
search: params.escalationPoliciesSearch,
|
||||
pageSize: params.escalationPoliciesPageSize
|
||||
? Number(params.escalationPoliciesPageSize)
|
||||
: undefined,
|
||||
pageNumber: params.escalationPoliciesPageNumber
|
||||
? Number(params.escalationPoliciesPageNumber)
|
||||
: undefined,
|
||||
}
|
||||
|
||||
case 'rootly_list_causes':
|
||||
return {
|
||||
...baseParams,
|
||||
search: params.causesSearch,
|
||||
pageSize: params.causesPageSize ? Number(params.causesPageSize) : undefined,
|
||||
pageNumber: params.causesPageNumber ? Number(params.causesPageNumber) : undefined,
|
||||
}
|
||||
|
||||
case 'rootly_list_playbooks':
|
||||
return {
|
||||
...baseParams,
|
||||
pageSize: params.playbooksPageSize ? Number(params.playbooksPageSize) : undefined,
|
||||
pageNumber: params.playbooksPageNumber
|
||||
? Number(params.playbooksPageNumber)
|
||||
: undefined,
|
||||
}
|
||||
|
||||
default:
|
||||
return baseParams
|
||||
}
|
||||
@@ -1101,6 +1635,58 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
retrospectivesSearch: { type: 'string', description: 'Search retrospectives' },
|
||||
retrospectivesPageSize: { type: 'string', description: 'Retrospectives page size' },
|
||||
retrospectivesPageNumber: { type: 'string', description: 'Retrospectives page number' },
|
||||
deleteIncidentId: { type: 'string', description: 'Incident ID to delete' },
|
||||
getAlertId: { type: 'string', description: 'Alert ID to retrieve' },
|
||||
updateAlertId: { type: 'string', description: 'Alert ID to update' },
|
||||
updateAlertSummary: { type: 'string', description: 'Updated alert summary' },
|
||||
updateAlertDescription: { type: 'string', description: 'Updated alert description' },
|
||||
updateAlertSource: { type: 'string', description: 'Updated alert source' },
|
||||
updateAlertServiceIds: { type: 'string', description: 'Updated alert service IDs' },
|
||||
updateAlertGroupIds: { type: 'string', description: 'Updated alert team IDs' },
|
||||
updateAlertEnvironmentIds: { type: 'string', description: 'Updated alert environment IDs' },
|
||||
updateAlertExternalId: { type: 'string', description: 'Updated external alert ID' },
|
||||
updateAlertExternalUrl: { type: 'string', description: 'Updated external URL' },
|
||||
updateAlertDeduplicationKey: { type: 'string', description: 'Updated deduplication key' },
|
||||
ackAlertId: { type: 'string', description: 'Alert ID to acknowledge' },
|
||||
resolveAlertId: { type: 'string', description: 'Alert ID to resolve' },
|
||||
resolveResolutionMessage: { type: 'string', description: 'Resolution message' },
|
||||
resolveRelatedIncidents: { type: 'string', description: 'Resolve related incidents' },
|
||||
actionItemIncidentId: { type: 'string', description: 'Incident ID for action item' },
|
||||
actionItemSummary: { type: 'string', description: 'Action item summary' },
|
||||
actionItemDescription: { type: 'string', description: 'Action item description' },
|
||||
actionItemKind: { type: 'string', description: 'Action item kind' },
|
||||
actionItemPriority: { type: 'string', description: 'Action item priority' },
|
||||
actionItemStatus: { type: 'string', description: 'Action item status' },
|
||||
actionItemAssignedToUserId: { type: 'string', description: 'Assigned user ID' },
|
||||
actionItemDueDate: { type: 'string', description: 'Action item due date' },
|
||||
listActionItemsIncidentId: { type: 'string', description: 'Incident ID for action items' },
|
||||
listActionItemsPageSize: { type: 'string', description: 'Action items page size' },
|
||||
listActionItemsPageNumber: { type: 'string', description: 'Action items page number' },
|
||||
usersSearch: { type: 'string', description: 'Search users' },
|
||||
usersEmail: { type: 'string', description: 'Filter users by email' },
|
||||
usersPageSize: { type: 'string', description: 'Users page size' },
|
||||
usersPageNumber: { type: 'string', description: 'Users page number' },
|
||||
onCallsScheduleIds: { type: 'string', description: 'Filter on-calls by schedule IDs' },
|
||||
onCallsEscalationPolicyIds: {
|
||||
type: 'string',
|
||||
description: 'Filter on-calls by escalation policy IDs',
|
||||
},
|
||||
onCallsUserIds: { type: 'string', description: 'Filter on-calls by user IDs' },
|
||||
onCallsServiceIds: { type: 'string', description: 'Filter on-calls by service IDs' },
|
||||
schedulesSearch: { type: 'string', description: 'Search schedules' },
|
||||
schedulesPageSize: { type: 'string', description: 'Schedules page size' },
|
||||
schedulesPageNumber: { type: 'string', description: 'Schedules page number' },
|
||||
escalationPoliciesSearch: { type: 'string', description: 'Search escalation policies' },
|
||||
escalationPoliciesPageSize: { type: 'string', description: 'Escalation policies page size' },
|
||||
escalationPoliciesPageNumber: {
|
||||
type: 'string',
|
||||
description: 'Escalation policies page number',
|
||||
},
|
||||
causesSearch: { type: 'string', description: 'Search causes' },
|
||||
causesPageSize: { type: 'string', description: 'Causes page size' },
|
||||
causesPageNumber: { type: 'string', description: 'Causes page number' },
|
||||
playbooksPageSize: { type: 'string', description: 'Playbooks page size' },
|
||||
playbooksPageNumber: { type: 'string', description: 'Playbooks page number' },
|
||||
},
|
||||
outputs: {
|
||||
incident: {
|
||||
@@ -1150,6 +1736,42 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
|
||||
type: 'json',
|
||||
description: 'List of retrospectives (id, title, status, url, timestamps)',
|
||||
},
|
||||
users: {
|
||||
type: 'json',
|
||||
description: 'List of users (id, name, email)',
|
||||
},
|
||||
onCalls: {
|
||||
type: 'json',
|
||||
description:
|
||||
'List of on-call entries (userId, userName, scheduleId, scheduleName, escalationPolicyId)',
|
||||
},
|
||||
schedules: {
|
||||
type: 'json',
|
||||
description: 'List of schedules (id, name, description)',
|
||||
},
|
||||
escalationPolicies: {
|
||||
type: 'json',
|
||||
description: 'List of escalation policies (id, name, description)',
|
||||
},
|
||||
causes: {
|
||||
type: 'json',
|
||||
description: 'List of causes (id, name, slug, description)',
|
||||
},
|
||||
playbooks: {
|
||||
type: 'json',
|
||||
description: 'List of playbooks (id, title, summary)',
|
||||
},
|
||||
actionItem: {
|
||||
type: 'json',
|
||||
description: 'Action item data (id, summary, description, kind, priority, status, dueDate)',
|
||||
},
|
||||
actionItems: {
|
||||
type: 'json',
|
||||
description:
|
||||
'List of action items (id, summary, description, kind, priority, status, dueDate)',
|
||||
},
|
||||
success: { type: 'boolean', description: 'Whether the operation succeeded' },
|
||||
message: { type: 'string', description: 'Operation result message' },
|
||||
totalCount: { type: 'number', description: 'Total count of items returned' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2009,19 +2009,32 @@ import {
|
||||
ripplingUpdateWorkLocationTool,
|
||||
} from '@/tools/rippling'
|
||||
import {
|
||||
rootlyAcknowledgeAlertTool,
|
||||
rootlyAddIncidentEventTool,
|
||||
rootlyCreateActionItemTool,
|
||||
rootlyCreateAlertTool,
|
||||
rootlyCreateIncidentTool,
|
||||
rootlyDeleteIncidentTool,
|
||||
rootlyGetAlertTool,
|
||||
rootlyGetIncidentTool,
|
||||
rootlyListActionItemsTool,
|
||||
rootlyListAlertsTool,
|
||||
rootlyListCausesTool,
|
||||
rootlyListEnvironmentsTool,
|
||||
rootlyListEscalationPoliciesTool,
|
||||
rootlyListFunctionalitiesTool,
|
||||
rootlyListIncidentsTool,
|
||||
rootlyListIncidentTypesTool,
|
||||
rootlyListOnCallsTool,
|
||||
rootlyListPlaybooksTool,
|
||||
rootlyListRetrospectivesTool,
|
||||
rootlyListSchedulesTool,
|
||||
rootlyListServicesTool,
|
||||
rootlyListSeveritiesTool,
|
||||
rootlyListTeamsTool,
|
||||
rootlyListUsersTool,
|
||||
rootlyResolveAlertTool,
|
||||
rootlyUpdateAlertTool,
|
||||
rootlyUpdateIncidentTool,
|
||||
} from '@/tools/rootly'
|
||||
import {
|
||||
@@ -3834,19 +3847,32 @@ export const tools: Record<string, ToolConfig> = {
|
||||
rippling_update_supergroup_inclusion_members: ripplingUpdateSupergroupInclusionMembersTool,
|
||||
rippling_update_title: ripplingUpdateTitleTool,
|
||||
rippling_update_work_location: ripplingUpdateWorkLocationTool,
|
||||
rootly_acknowledge_alert: rootlyAcknowledgeAlertTool,
|
||||
rootly_add_incident_event: rootlyAddIncidentEventTool,
|
||||
rootly_create_action_item: rootlyCreateActionItemTool,
|
||||
rootly_create_alert: rootlyCreateAlertTool,
|
||||
rootly_create_incident: rootlyCreateIncidentTool,
|
||||
rootly_delete_incident: rootlyDeleteIncidentTool,
|
||||
rootly_get_alert: rootlyGetAlertTool,
|
||||
rootly_get_incident: rootlyGetIncidentTool,
|
||||
rootly_list_action_items: rootlyListActionItemsTool,
|
||||
rootly_list_alerts: rootlyListAlertsTool,
|
||||
rootly_list_causes: rootlyListCausesTool,
|
||||
rootly_list_environments: rootlyListEnvironmentsTool,
|
||||
rootly_list_escalation_policies: rootlyListEscalationPoliciesTool,
|
||||
rootly_list_functionalities: rootlyListFunctionalitiesTool,
|
||||
rootly_list_incident_types: rootlyListIncidentTypesTool,
|
||||
rootly_list_incidents: rootlyListIncidentsTool,
|
||||
rootly_list_on_calls: rootlyListOnCallsTool,
|
||||
rootly_list_playbooks: rootlyListPlaybooksTool,
|
||||
rootly_list_retrospectives: rootlyListRetrospectivesTool,
|
||||
rootly_list_schedules: rootlyListSchedulesTool,
|
||||
rootly_list_services: rootlyListServicesTool,
|
||||
rootly_list_severities: rootlyListSeveritiesTool,
|
||||
rootly_list_teams: rootlyListTeamsTool,
|
||||
rootly_list_users: rootlyListUsersTool,
|
||||
rootly_resolve_alert: rootlyResolveAlertTool,
|
||||
rootly_update_alert: rootlyUpdateAlertTool,
|
||||
rootly_update_incident: rootlyUpdateIncidentTool,
|
||||
google_drive_copy: googleDriveCopyTool,
|
||||
google_drive_create_folder: googleDriveCreateFolderTool,
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import type {
|
||||
RootlyAcknowledgeAlertParams,
|
||||
RootlyAcknowledgeAlertResponse,
|
||||
} from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyAcknowledgeAlertTool: ToolConfig<
|
||||
RootlyAcknowledgeAlertParams,
|
||||
RootlyAcknowledgeAlertResponse
|
||||
> = {
|
||||
id: 'rootly_acknowledge_alert',
|
||||
name: 'Rootly Acknowledge Alert',
|
||||
description: 'Acknowledge an alert in Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
alertId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the alert to acknowledge',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.rootly.com/v1/alerts/${params.alertId.trim()}/acknowledge`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: () => ({ data: {} }),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { alert: {} as RootlyAcknowledgeAlertResponse['output']['alert'] },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const attrs = data.data?.attributes || {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
alert: {
|
||||
id: data.data?.id ?? null,
|
||||
shortId: attrs.short_id ?? null,
|
||||
summary: attrs.summary ?? '',
|
||||
description: attrs.description ?? null,
|
||||
source: attrs.source ?? null,
|
||||
status: attrs.status ?? null,
|
||||
externalId: attrs.external_id ?? null,
|
||||
externalUrl: attrs.external_url ?? null,
|
||||
deduplicationKey: attrs.deduplication_key ?? null,
|
||||
createdAt: attrs.created_at ?? '',
|
||||
updatedAt: attrs.updated_at ?? '',
|
||||
startedAt: attrs.started_at ?? null,
|
||||
endedAt: attrs.ended_at ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
alert: {
|
||||
type: 'object',
|
||||
description: 'The acknowledged alert',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique alert ID' },
|
||||
shortId: { type: 'string', description: 'Short alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
description: { type: 'string', description: 'Alert description' },
|
||||
source: { type: 'string', description: 'Alert source' },
|
||||
status: { type: 'string', description: 'Alert status' },
|
||||
externalId: { type: 'string', description: 'External ID' },
|
||||
externalUrl: { type: 'string', description: 'External URL' },
|
||||
deduplicationKey: { type: 'string', description: 'Deduplication key' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
startedAt: { type: 'string', description: 'Start date' },
|
||||
endedAt: { type: 'string', description: 'End date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import type {
|
||||
RootlyCreateActionItemParams,
|
||||
RootlyCreateActionItemResponse,
|
||||
} from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyCreateActionItemTool: ToolConfig<
|
||||
RootlyCreateActionItemParams,
|
||||
RootlyCreateActionItemResponse
|
||||
> = {
|
||||
id: 'rootly_create_action_item',
|
||||
name: 'Rootly Create Action Item',
|
||||
description: 'Create a new action item for an incident in Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident to add the action item to',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The title of the action item',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'A detailed description of the action item',
|
||||
},
|
||||
kind: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The kind of action item (task, follow_up)',
|
||||
},
|
||||
priority: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Priority level (high, medium, low)',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Action item status (open, in_progress, cancelled, done)',
|
||||
},
|
||||
assignedToUserId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The user ID to assign the action item to',
|
||||
},
|
||||
dueDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Due date for the action item',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.rootly.com/v1/incidents/${params.incidentId.trim()}/action_items`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const attributes: Record<string, unknown> = {
|
||||
summary: params.summary,
|
||||
}
|
||||
if (params.description) attributes.description = params.description
|
||||
if (params.kind) attributes.kind = params.kind
|
||||
if (params.priority) attributes.priority = params.priority
|
||||
if (params.status) attributes.status = params.status
|
||||
if (params.assignedToUserId) {
|
||||
const numericId = Number.parseInt(params.assignedToUserId, 10)
|
||||
if (!Number.isNaN(numericId)) attributes.assigned_to_user_id = numericId
|
||||
}
|
||||
if (params.dueDate) attributes.due_date = params.dueDate
|
||||
return { data: { type: 'incident_action_items', attributes } }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { actionItem: {} as RootlyCreateActionItemResponse['output']['actionItem'] },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const attrs = data.data?.attributes || {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
actionItem: {
|
||||
id: data.data?.id ?? null,
|
||||
summary: attrs.summary ?? '',
|
||||
description: attrs.description ?? null,
|
||||
kind: attrs.kind ?? null,
|
||||
priority: attrs.priority ?? null,
|
||||
status: attrs.status ?? null,
|
||||
dueDate: attrs.due_date ?? null,
|
||||
createdAt: attrs.created_at ?? '',
|
||||
updatedAt: attrs.updated_at ?? '',
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
actionItem: {
|
||||
type: 'object',
|
||||
description: 'The created action item',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique action item ID' },
|
||||
summary: { type: 'string', description: 'Action item title' },
|
||||
description: { type: 'string', description: 'Action item description' },
|
||||
kind: { type: 'string', description: 'Action item kind (task, follow_up)' },
|
||||
priority: { type: 'string', description: 'Priority level' },
|
||||
status: { type: 'string', description: 'Action item status' },
|
||||
dueDate: { type: 'string', description: 'Due date' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -124,6 +124,7 @@ export const rootlyCreateAlertTool: ToolConfig<RootlyCreateAlertParams, RootlyCr
|
||||
output: {
|
||||
alert: {
|
||||
id: data.data?.id ?? null,
|
||||
shortId: attrs.short_id ?? null,
|
||||
summary: attrs.summary ?? '',
|
||||
description: attrs.description ?? null,
|
||||
source: attrs.source ?? null,
|
||||
@@ -133,6 +134,8 @@ export const rootlyCreateAlertTool: ToolConfig<RootlyCreateAlertParams, RootlyCr
|
||||
deduplicationKey: attrs.deduplication_key ?? null,
|
||||
createdAt: attrs.created_at ?? '',
|
||||
updatedAt: attrs.updated_at ?? '',
|
||||
startedAt: attrs.started_at ?? null,
|
||||
endedAt: attrs.ended_at ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -144,6 +147,7 @@ export const rootlyCreateAlertTool: ToolConfig<RootlyCreateAlertParams, RootlyCr
|
||||
description: 'The created alert',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique alert ID' },
|
||||
shortId: { type: 'string', description: 'Short alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
description: { type: 'string', description: 'Alert description' },
|
||||
source: { type: 'string', description: 'Alert source' },
|
||||
@@ -153,6 +157,8 @@ export const rootlyCreateAlertTool: ToolConfig<RootlyCreateAlertParams, RootlyCr
|
||||
deduplicationKey: { type: 'string', description: 'Deduplication key' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
startedAt: { type: 'string', description: 'Start date' },
|
||||
endedAt: { type: 'string', description: 'End date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import type { RootlyDeleteIncidentParams, RootlyDeleteIncidentResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyDeleteIncidentTool: ToolConfig<
|
||||
RootlyDeleteIncidentParams,
|
||||
RootlyDeleteIncidentResponse
|
||||
> = {
|
||||
id: 'rootly_delete_incident',
|
||||
name: 'Rootly Delete Incident',
|
||||
description: 'Delete an incident by ID from Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.rootly.com/v1/incidents/${params.incidentId.trim()}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: {
|
||||
success: false,
|
||||
message:
|
||||
errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
},
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
success: true,
|
||||
message: 'Incident deleted successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Whether the deletion succeeded' },
|
||||
message: { type: 'string', description: 'Result message' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import type { RootlyGetAlertParams, RootlyGetAlertResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyGetAlertTool: ToolConfig<RootlyGetAlertParams, RootlyGetAlertResponse> = {
|
||||
id: 'rootly_get_alert',
|
||||
name: 'Rootly Get Alert',
|
||||
description: 'Retrieve a single alert by ID from Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
alertId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the alert to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.rootly.com/v1/alerts/${params.alertId.trim()}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { alert: {} as RootlyGetAlertResponse['output']['alert'] },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const attrs = data.data?.attributes || {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
alert: {
|
||||
id: data.data?.id ?? null,
|
||||
shortId: attrs.short_id ?? null,
|
||||
summary: attrs.summary ?? '',
|
||||
description: attrs.description ?? null,
|
||||
source: attrs.source ?? null,
|
||||
status: attrs.status ?? null,
|
||||
externalId: attrs.external_id ?? null,
|
||||
externalUrl: attrs.external_url ?? null,
|
||||
deduplicationKey: attrs.deduplication_key ?? null,
|
||||
createdAt: attrs.created_at ?? '',
|
||||
updatedAt: attrs.updated_at ?? '',
|
||||
startedAt: attrs.started_at ?? null,
|
||||
endedAt: attrs.ended_at ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
alert: {
|
||||
type: 'object',
|
||||
description: 'The alert details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique alert ID' },
|
||||
shortId: { type: 'string', description: 'Short alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
description: { type: 'string', description: 'Alert description' },
|
||||
source: { type: 'string', description: 'Alert source' },
|
||||
status: { type: 'string', description: 'Alert status' },
|
||||
externalId: { type: 'string', description: 'External ID' },
|
||||
externalUrl: { type: 'string', description: 'External URL' },
|
||||
deduplicationKey: { type: 'string', description: 'Deduplication key' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
startedAt: { type: 'string', description: 'Start date' },
|
||||
endedAt: { type: 'string', description: 'End date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,15 +1,28 @@
|
||||
export { rootlyAcknowledgeAlertTool } from '@/tools/rootly/acknowledge_alert'
|
||||
export { rootlyAddIncidentEventTool } from '@/tools/rootly/add_incident_event'
|
||||
export { rootlyCreateActionItemTool } from '@/tools/rootly/create_action_item'
|
||||
export { rootlyCreateAlertTool } from '@/tools/rootly/create_alert'
|
||||
export { rootlyCreateIncidentTool } from '@/tools/rootly/create_incident'
|
||||
export { rootlyDeleteIncidentTool } from '@/tools/rootly/delete_incident'
|
||||
export { rootlyGetAlertTool } from '@/tools/rootly/get_alert'
|
||||
export { rootlyGetIncidentTool } from '@/tools/rootly/get_incident'
|
||||
export { rootlyListActionItemsTool } from '@/tools/rootly/list_action_items'
|
||||
export { rootlyListAlertsTool } from '@/tools/rootly/list_alerts'
|
||||
export { rootlyListCausesTool } from '@/tools/rootly/list_causes'
|
||||
export { rootlyListEnvironmentsTool } from '@/tools/rootly/list_environments'
|
||||
export { rootlyListEscalationPoliciesTool } from '@/tools/rootly/list_escalation_policies'
|
||||
export { rootlyListFunctionalitiesTool } from '@/tools/rootly/list_functionalities'
|
||||
export { rootlyListIncidentTypesTool } from '@/tools/rootly/list_incident_types'
|
||||
export { rootlyListIncidentsTool } from '@/tools/rootly/list_incidents'
|
||||
export { rootlyListOnCallsTool } from '@/tools/rootly/list_on_calls'
|
||||
export { rootlyListPlaybooksTool } from '@/tools/rootly/list_playbooks'
|
||||
export { rootlyListRetrospectivesTool } from '@/tools/rootly/list_retrospectives'
|
||||
export { rootlyListSchedulesTool } from '@/tools/rootly/list_schedules'
|
||||
export { rootlyListServicesTool } from '@/tools/rootly/list_services'
|
||||
export { rootlyListSeveritiesTool } from '@/tools/rootly/list_severities'
|
||||
export { rootlyListTeamsTool } from '@/tools/rootly/list_teams'
|
||||
export { rootlyListUsersTool } from '@/tools/rootly/list_users'
|
||||
export { rootlyResolveAlertTool } from '@/tools/rootly/resolve_alert'
|
||||
export * from '@/tools/rootly/types'
|
||||
export { rootlyUpdateAlertTool } from '@/tools/rootly/update_alert'
|
||||
export { rootlyUpdateIncidentTool } from '@/tools/rootly/update_incident'
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import type {
|
||||
RootlyListActionItemsParams,
|
||||
RootlyListActionItemsResponse,
|
||||
} from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListActionItemsTool: ToolConfig<
|
||||
RootlyListActionItemsParams,
|
||||
RootlyListActionItemsResponse
|
||||
> = {
|
||||
id: 'rootly_list_action_items',
|
||||
name: 'Rootly List Action Items',
|
||||
description: 'List action items for an incident in Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
incidentId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the incident to list action items for',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of items per page (default: 20)',
|
||||
},
|
||||
pageNumber: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page number for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.pageSize) queryParams.set('page[size]', String(params.pageSize))
|
||||
if (params.pageNumber) queryParams.set('page[number]', String(params.pageNumber))
|
||||
const qs = queryParams.toString()
|
||||
return `https://api.rootly.com/v1/incidents/${params.incidentId.trim()}/action_items${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { actionItems: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const actionItems = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
summary: (attrs.summary as string) ?? '',
|
||||
description: (attrs.description as string) ?? null,
|
||||
kind: (attrs.kind as string) ?? null,
|
||||
priority: (attrs.priority as string) ?? null,
|
||||
status: (attrs.status as string) ?? null,
|
||||
dueDate: (attrs.due_date as string) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
actionItems,
|
||||
totalCount: data.meta?.total_count ?? actionItems.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
actionItems: {
|
||||
type: 'array',
|
||||
description: 'List of action items',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique action item ID' },
|
||||
summary: { type: 'string', description: 'Action item title' },
|
||||
description: { type: 'string', description: 'Action item description' },
|
||||
kind: { type: 'string', description: 'Action item kind (task, follow_up)' },
|
||||
priority: { type: 'string', description: 'Priority level' },
|
||||
status: { type: 'string', description: 'Action item status' },
|
||||
dueDate: { type: 'string', description: 'Due date' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of action items returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -93,6 +93,7 @@ export const rootlyListAlertsTool: ToolConfig<RootlyListAlertsParams, RootlyList
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
shortId: (attrs.short_id as string) ?? null,
|
||||
summary: (attrs.summary as string) ?? '',
|
||||
description: (attrs.description as string) ?? null,
|
||||
source: (attrs.source as string) ?? null,
|
||||
@@ -102,6 +103,8 @@ export const rootlyListAlertsTool: ToolConfig<RootlyListAlertsParams, RootlyList
|
||||
deduplicationKey: (attrs.deduplication_key as string) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
startedAt: (attrs.started_at as string) ?? null,
|
||||
endedAt: (attrs.ended_at as string) ?? null,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -122,6 +125,7 @@ export const rootlyListAlertsTool: ToolConfig<RootlyListAlertsParams, RootlyList
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique alert ID' },
|
||||
shortId: { type: 'string', description: 'Short alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
description: { type: 'string', description: 'Alert description' },
|
||||
source: { type: 'string', description: 'Alert source' },
|
||||
@@ -131,6 +135,8 @@ export const rootlyListAlertsTool: ToolConfig<RootlyListAlertsParams, RootlyList
|
||||
deduplicationKey: { type: 'string', description: 'Deduplication key' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
startedAt: { type: 'string', description: 'Start date' },
|
||||
endedAt: { type: 'string', description: 'End date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
import type { RootlyListCausesParams, RootlyListCausesResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListCausesTool: ToolConfig<RootlyListCausesParams, RootlyListCausesResponse> = {
|
||||
id: 'rootly_list_causes',
|
||||
name: 'Rootly List Causes',
|
||||
description: 'List causes from Rootly with optional search filtering.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
search: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search term to filter causes',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of items per page (default: 20)',
|
||||
},
|
||||
pageNumber: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page number for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.search) queryParams.set('filter[search]', params.search)
|
||||
if (params.pageSize) queryParams.set('page[size]', String(params.pageSize))
|
||||
if (params.pageNumber) queryParams.set('page[number]', String(params.pageNumber))
|
||||
const qs = queryParams.toString()
|
||||
return `https://api.rootly.com/v1/causes${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { causes: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const causes = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
name: (attrs.name as string) ?? '',
|
||||
slug: (attrs.slug as string) ?? null,
|
||||
description: (attrs.description as string) ?? null,
|
||||
position: (attrs.position as number) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
causes,
|
||||
totalCount: data.meta?.total_count ?? causes.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
causes: {
|
||||
type: 'array',
|
||||
description: 'List of causes',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique cause ID' },
|
||||
name: { type: 'string', description: 'Cause name' },
|
||||
slug: { type: 'string', description: 'Cause slug' },
|
||||
description: { type: 'string', description: 'Cause description' },
|
||||
position: { type: 'number', description: 'Cause position' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of causes returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import type {
|
||||
RootlyListEscalationPoliciesParams,
|
||||
RootlyListEscalationPoliciesResponse,
|
||||
} from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListEscalationPoliciesTool: ToolConfig<
|
||||
RootlyListEscalationPoliciesParams,
|
||||
RootlyListEscalationPoliciesResponse
|
||||
> = {
|
||||
id: 'rootly_list_escalation_policies',
|
||||
name: 'Rootly List Escalation Policies',
|
||||
description: 'List escalation policies from Rootly with optional search filtering.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
search: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search term to filter escalation policies',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of items per page (default: 20)',
|
||||
},
|
||||
pageNumber: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page number for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.search) queryParams.set('filter[search]', params.search)
|
||||
if (params.pageSize) queryParams.set('page[size]', String(params.pageSize))
|
||||
if (params.pageNumber) queryParams.set('page[number]', String(params.pageNumber))
|
||||
const qs = queryParams.toString()
|
||||
return `https://api.rootly.com/v1/escalation_policies${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { escalationPolicies: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const escalationPolicies = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
name: (attrs.name as string) ?? '',
|
||||
description: (attrs.description as string) ?? null,
|
||||
repeatCount: (attrs.repeat_count as number) ?? null,
|
||||
groupIds: (attrs.group_ids as string[]) ?? null,
|
||||
serviceIds: (attrs.service_ids as string[]) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
escalationPolicies,
|
||||
totalCount: data.meta?.total_count ?? escalationPolicies.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
escalationPolicies: {
|
||||
type: 'array',
|
||||
description: 'List of escalation policies',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique escalation policy ID' },
|
||||
name: { type: 'string', description: 'Escalation policy name' },
|
||||
description: { type: 'string', description: 'Escalation policy description' },
|
||||
repeatCount: { type: 'number', description: 'Number of times to repeat escalation' },
|
||||
groupIds: { type: 'array', description: 'Associated group IDs' },
|
||||
serviceIds: { type: 'array', description: 'Associated service IDs' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of escalation policies returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import type { RootlyListOnCallsParams, RootlyListOnCallsResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListOnCallsTool: ToolConfig<RootlyListOnCallsParams, RootlyListOnCallsResponse> =
|
||||
{
|
||||
id: 'rootly_list_on_calls',
|
||||
name: 'Rootly List On-Calls',
|
||||
description: 'List current on-call entries from Rootly with optional filtering.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
scheduleIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated schedule IDs to filter by',
|
||||
},
|
||||
escalationPolicyIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated escalation policy IDs to filter by',
|
||||
},
|
||||
userIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated user IDs to filter by',
|
||||
},
|
||||
serviceIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated service IDs to filter by',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.scheduleIds) queryParams.set('filter[schedule_ids]', params.scheduleIds)
|
||||
if (params.escalationPolicyIds)
|
||||
queryParams.set('filter[escalation_policy_ids]', params.escalationPolicyIds)
|
||||
if (params.userIds) queryParams.set('filter[user_ids]', params.userIds)
|
||||
if (params.serviceIds) queryParams.set('filter[service_ids]', params.serviceIds)
|
||||
queryParams.set('include', 'user,schedule,escalation_policy')
|
||||
return `https://api.rootly.com/v1/oncalls?${queryParams.toString()}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { onCalls: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const included = (data.included || []) as Record<string, unknown>[]
|
||||
const findIncluded = (
|
||||
type: string,
|
||||
id: string | null
|
||||
): Record<string, unknown> | undefined =>
|
||||
id ? included.find((i) => i.type === type && i.id === id) : undefined
|
||||
|
||||
const onCalls = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
const rels = (item.relationships || {}) as Record<string, Record<string, unknown>>
|
||||
|
||||
const userId = ((rels.user?.data as Record<string, unknown>)?.id as string) ?? null
|
||||
const scheduleId = ((rels.schedule?.data as Record<string, unknown>)?.id as string) ?? null
|
||||
const escalationPolicyId =
|
||||
((rels.escalation_policy?.data as Record<string, unknown>)?.id as string) ?? null
|
||||
|
||||
const userIncl = findIncluded('users', userId)
|
||||
const scheduleIncl = findIncluded('schedules', scheduleId)
|
||||
|
||||
return {
|
||||
id: (item.id as string) ?? null,
|
||||
userId,
|
||||
userName: userIncl
|
||||
? (((userIncl.attributes as Record<string, unknown>)?.full_name as string) ?? null)
|
||||
: null,
|
||||
scheduleId,
|
||||
scheduleName: scheduleIncl
|
||||
? (((scheduleIncl.attributes as Record<string, unknown>)?.name as string) ?? null)
|
||||
: null,
|
||||
escalationPolicyId,
|
||||
startTime: (attrs.start_time as string) ?? null,
|
||||
endTime: (attrs.end_time as string) ?? null,
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
onCalls,
|
||||
totalCount: data.meta?.total_count ?? onCalls.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
onCalls: {
|
||||
type: 'array',
|
||||
description: 'List of on-call entries',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique on-call entry ID' },
|
||||
userId: { type: 'string', description: 'ID of the on-call user' },
|
||||
userName: { type: 'string', description: 'Name of the on-call user' },
|
||||
scheduleId: { type: 'string', description: 'ID of the associated schedule' },
|
||||
scheduleName: { type: 'string', description: 'Name of the associated schedule' },
|
||||
escalationPolicyId: {
|
||||
type: 'string',
|
||||
description: 'ID of the associated escalation policy',
|
||||
},
|
||||
startTime: { type: 'string', description: 'On-call start time' },
|
||||
endTime: { type: 'string', description: 'On-call end time' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of on-call entries returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import type { RootlyListPlaybooksParams, RootlyListPlaybooksResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListPlaybooksTool: ToolConfig<
|
||||
RootlyListPlaybooksParams,
|
||||
RootlyListPlaybooksResponse
|
||||
> = {
|
||||
id: 'rootly_list_playbooks',
|
||||
name: 'Rootly List Playbooks',
|
||||
description: 'List playbooks from Rootly with pagination support.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of items per page (default: 20)',
|
||||
},
|
||||
pageNumber: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page number for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.pageSize) queryParams.set('page[size]', String(params.pageSize))
|
||||
if (params.pageNumber) queryParams.set('page[number]', String(params.pageNumber))
|
||||
const qs = queryParams.toString()
|
||||
return `https://api.rootly.com/v1/playbooks${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { playbooks: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const playbooks = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
title: (attrs.title as string) ?? '',
|
||||
summary: (attrs.summary as string) ?? null,
|
||||
externalUrl: (attrs.external_url as string) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
playbooks,
|
||||
totalCount: data.meta?.total_count ?? playbooks.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
playbooks: {
|
||||
type: 'array',
|
||||
description: 'List of playbooks',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique playbook ID' },
|
||||
title: { type: 'string', description: 'Playbook title' },
|
||||
summary: { type: 'string', description: 'Playbook summary' },
|
||||
externalUrl: { type: 'string', description: 'External URL' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of playbooks returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { RootlyListSchedulesParams, RootlyListSchedulesResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListSchedulesTool: ToolConfig<
|
||||
RootlyListSchedulesParams,
|
||||
RootlyListSchedulesResponse
|
||||
> = {
|
||||
id: 'rootly_list_schedules',
|
||||
name: 'Rootly List Schedules',
|
||||
description: 'List on-call schedules from Rootly with optional search filtering.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
search: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search term to filter schedules',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of items per page (default: 20)',
|
||||
},
|
||||
pageNumber: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page number for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.search) queryParams.set('filter[search]', params.search)
|
||||
if (params.pageSize) queryParams.set('page[size]', String(params.pageSize))
|
||||
if (params.pageNumber) queryParams.set('page[number]', String(params.pageNumber))
|
||||
const qs = queryParams.toString()
|
||||
return `https://api.rootly.com/v1/schedules${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { schedules: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const schedules = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
name: (attrs.name as string) ?? '',
|
||||
description: (attrs.description as string) ?? null,
|
||||
allTimeCoverage: (attrs.all_time_coverage as boolean) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
schedules,
|
||||
totalCount: data.meta?.total_count ?? schedules.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
schedules: {
|
||||
type: 'array',
|
||||
description: 'List of schedules',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique schedule ID' },
|
||||
name: { type: 'string', description: 'Schedule name' },
|
||||
description: { type: 'string', description: 'Schedule description' },
|
||||
allTimeCoverage: {
|
||||
type: 'boolean',
|
||||
description: 'Whether schedule provides 24/7 coverage',
|
||||
},
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of schedules returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
import type { RootlyListUsersParams, RootlyListUsersResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyListUsersTool: ToolConfig<RootlyListUsersParams, RootlyListUsersResponse> = {
|
||||
id: 'rootly_list_users',
|
||||
name: 'Rootly List Users',
|
||||
description: 'List users from Rootly with optional search and email filtering.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
search: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search term to filter users',
|
||||
},
|
||||
email: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter users by email address',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of items per page (default: 20)',
|
||||
},
|
||||
pageNumber: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page number for pagination',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.search) queryParams.set('filter[search]', params.search)
|
||||
if (params.email) queryParams.set('filter[email]', params.email)
|
||||
if (params.pageSize) queryParams.set('page[size]', String(params.pageSize))
|
||||
if (params.pageNumber) queryParams.set('page[number]', String(params.pageNumber))
|
||||
const qs = queryParams.toString()
|
||||
return `https://api.rootly.com/v1/users${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { users: [], totalCount: 0 },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const users = (data.data || []).map((item: Record<string, unknown>) => {
|
||||
const attrs = (item.attributes || {}) as Record<string, unknown>
|
||||
return {
|
||||
id: item.id ?? null,
|
||||
email: (attrs.email as string) ?? '',
|
||||
firstName: (attrs.first_name as string) ?? null,
|
||||
lastName: (attrs.last_name as string) ?? null,
|
||||
fullName: (attrs.full_name as string) ?? null,
|
||||
timeZone: (attrs.time_zone as string) ?? null,
|
||||
createdAt: (attrs.created_at as string) ?? '',
|
||||
updatedAt: (attrs.updated_at as string) ?? '',
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
users,
|
||||
totalCount: data.meta?.total_count ?? users.length,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
users: {
|
||||
type: 'array',
|
||||
description: 'List of users',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique user ID' },
|
||||
email: { type: 'string', description: 'User email address' },
|
||||
firstName: { type: 'string', description: 'User first name' },
|
||||
lastName: { type: 'string', description: 'User last name' },
|
||||
fullName: { type: 'string', description: 'User full name' },
|
||||
timeZone: { type: 'string', description: 'User time zone' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: {
|
||||
type: 'number',
|
||||
description: 'Total number of users returned',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { RootlyResolveAlertParams, RootlyResolveAlertResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyResolveAlertTool: ToolConfig<
|
||||
RootlyResolveAlertParams,
|
||||
RootlyResolveAlertResponse
|
||||
> = {
|
||||
id: 'rootly_resolve_alert',
|
||||
name: 'Rootly Resolve Alert',
|
||||
description: 'Resolve an alert in Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
alertId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the alert to resolve',
|
||||
},
|
||||
resolutionMessage: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Message describing how the alert was resolved',
|
||||
},
|
||||
resolveRelatedIncidents: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to also resolve related incidents',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.rootly.com/v1/alerts/${params.alertId.trim()}/resolve`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const attributes: Record<string, unknown> = {}
|
||||
if (params.resolutionMessage) attributes.resolution_message = params.resolutionMessage
|
||||
if (params.resolveRelatedIncidents !== undefined)
|
||||
attributes.resolve_related_incidents = params.resolveRelatedIncidents
|
||||
if (Object.keys(attributes).length === 0) return { data: {} }
|
||||
return { data: { type: 'alerts', attributes } }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { alert: {} as RootlyResolveAlertResponse['output']['alert'] },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const attrs = data.data?.attributes || {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
alert: {
|
||||
id: data.data?.id ?? null,
|
||||
shortId: attrs.short_id ?? null,
|
||||
summary: attrs.summary ?? '',
|
||||
description: attrs.description ?? null,
|
||||
source: attrs.source ?? null,
|
||||
status: attrs.status ?? null,
|
||||
externalId: attrs.external_id ?? null,
|
||||
externalUrl: attrs.external_url ?? null,
|
||||
deduplicationKey: attrs.deduplication_key ?? null,
|
||||
createdAt: attrs.created_at ?? '',
|
||||
updatedAt: attrs.updated_at ?? '',
|
||||
startedAt: attrs.started_at ?? null,
|
||||
endedAt: attrs.ended_at ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
alert: {
|
||||
type: 'object',
|
||||
description: 'The resolved alert',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique alert ID' },
|
||||
shortId: { type: 'string', description: 'Short alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
description: { type: 'string', description: 'Alert description' },
|
||||
source: { type: 'string', description: 'Alert source' },
|
||||
status: { type: 'string', description: 'Alert status' },
|
||||
externalId: { type: 'string', description: 'External ID' },
|
||||
externalUrl: { type: 'string', description: 'External URL' },
|
||||
deduplicationKey: { type: 'string', description: 'Deduplication key' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
startedAt: { type: 'string', description: 'Start date' },
|
||||
endedAt: { type: 'string', description: 'End date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -121,6 +121,7 @@ export interface RootlyCreateAlertParams extends RootlyBaseParams {
|
||||
|
||||
export interface RootlyAlertData {
|
||||
id: string | null
|
||||
shortId: string | null
|
||||
summary: string
|
||||
description: string | null
|
||||
source: string | null
|
||||
@@ -130,6 +131,8 @@ export interface RootlyAlertData {
|
||||
deduplicationKey: string | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
startedAt: string | null
|
||||
endedAt: string | null
|
||||
}
|
||||
|
||||
export interface RootlyCreateAlertResponse extends ToolResponse {
|
||||
@@ -323,6 +326,109 @@ export interface RootlyListIncidentTypesResponse extends ToolResponse {
|
||||
}
|
||||
}
|
||||
|
||||
/** List Causes */
|
||||
export interface RootlyListCausesParams extends RootlyBaseParams {
|
||||
search?: string
|
||||
pageSize?: number
|
||||
pageNumber?: number
|
||||
}
|
||||
|
||||
export interface RootlyCauseData {
|
||||
id: string | null
|
||||
name: string
|
||||
slug: string | null
|
||||
description: string | null
|
||||
position: number | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface RootlyListCausesResponse extends ToolResponse {
|
||||
output: {
|
||||
causes: RootlyCauseData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** List Playbooks */
|
||||
export interface RootlyListPlaybooksParams extends RootlyBaseParams {
|
||||
pageSize?: number
|
||||
pageNumber?: number
|
||||
}
|
||||
|
||||
export interface RootlyPlaybookData {
|
||||
id: string | null
|
||||
title: string
|
||||
summary: string | null
|
||||
externalUrl: string | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface RootlyListPlaybooksResponse extends ToolResponse {
|
||||
output: {
|
||||
playbooks: RootlyPlaybookData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** Delete Incident */
|
||||
export interface RootlyDeleteIncidentParams extends RootlyBaseParams {
|
||||
incidentId: string
|
||||
}
|
||||
|
||||
export interface RootlyDeleteIncidentResponse extends ToolResponse {
|
||||
output: {
|
||||
success: boolean
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
/** Action Item Data */
|
||||
export interface RootlyActionItemData {
|
||||
id: string | null
|
||||
summary: string
|
||||
description: string | null
|
||||
kind: string | null
|
||||
priority: string | null
|
||||
status: string | null
|
||||
dueDate: string | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
/** Create Action Item */
|
||||
export interface RootlyCreateActionItemParams extends RootlyBaseParams {
|
||||
incidentId: string
|
||||
summary: string
|
||||
description?: string
|
||||
kind?: string
|
||||
priority?: string
|
||||
status?: string
|
||||
assignedToUserId?: string
|
||||
dueDate?: string
|
||||
}
|
||||
|
||||
export interface RootlyCreateActionItemResponse extends ToolResponse {
|
||||
output: {
|
||||
actionItem: RootlyActionItemData
|
||||
}
|
||||
}
|
||||
|
||||
/** List Action Items */
|
||||
export interface RootlyListActionItemsParams extends RootlyBaseParams {
|
||||
incidentId: string
|
||||
pageSize?: number
|
||||
pageNumber?: number
|
||||
}
|
||||
|
||||
export interface RootlyListActionItemsResponse extends ToolResponse {
|
||||
output: {
|
||||
actionItems: RootlyActionItemData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** List Functionalities */
|
||||
export interface RootlyListFunctionalitiesParams extends RootlyBaseParams {
|
||||
search?: string
|
||||
@@ -347,15 +453,177 @@ export interface RootlyListFunctionalitiesResponse extends ToolResponse {
|
||||
}
|
||||
}
|
||||
|
||||
/** Get Alert */
|
||||
export interface RootlyGetAlertParams extends RootlyBaseParams {
|
||||
alertId: string
|
||||
}
|
||||
|
||||
export interface RootlyGetAlertResponse extends ToolResponse {
|
||||
output: {
|
||||
alert: RootlyAlertData
|
||||
}
|
||||
}
|
||||
|
||||
/** Update Alert */
|
||||
export interface RootlyUpdateAlertParams extends RootlyBaseParams {
|
||||
alertId: string
|
||||
summary?: string
|
||||
description?: string
|
||||
source?: string
|
||||
serviceIds?: string
|
||||
groupIds?: string
|
||||
environmentIds?: string
|
||||
externalId?: string
|
||||
externalUrl?: string
|
||||
deduplicationKey?: string
|
||||
}
|
||||
|
||||
export interface RootlyUpdateAlertResponse extends ToolResponse {
|
||||
output: {
|
||||
alert: RootlyAlertData
|
||||
}
|
||||
}
|
||||
|
||||
/** Acknowledge Alert */
|
||||
export interface RootlyAcknowledgeAlertParams extends RootlyBaseParams {
|
||||
alertId: string
|
||||
}
|
||||
|
||||
export interface RootlyAcknowledgeAlertResponse extends ToolResponse {
|
||||
output: {
|
||||
alert: RootlyAlertData
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolve Alert */
|
||||
export interface RootlyResolveAlertParams extends RootlyBaseParams {
|
||||
alertId: string
|
||||
resolutionMessage?: string
|
||||
resolveRelatedIncidents?: boolean
|
||||
}
|
||||
|
||||
export interface RootlyResolveAlertResponse extends ToolResponse {
|
||||
output: {
|
||||
alert: RootlyAlertData
|
||||
}
|
||||
}
|
||||
|
||||
/** List Users */
|
||||
export interface RootlyListUsersParams extends RootlyBaseParams {
|
||||
search?: string
|
||||
email?: string
|
||||
pageSize?: number
|
||||
pageNumber?: number
|
||||
}
|
||||
|
||||
export interface RootlyUserData {
|
||||
id: string | null
|
||||
email: string
|
||||
firstName: string | null
|
||||
lastName: string | null
|
||||
fullName: string | null
|
||||
timeZone: string | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface RootlyListUsersResponse extends ToolResponse {
|
||||
output: {
|
||||
users: RootlyUserData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** List On-Calls */
|
||||
export interface RootlyListOnCallsParams extends RootlyBaseParams {
|
||||
scheduleIds?: string
|
||||
escalationPolicyIds?: string
|
||||
userIds?: string
|
||||
serviceIds?: string
|
||||
}
|
||||
|
||||
export interface RootlyOnCallData {
|
||||
id: string | null
|
||||
userId: string | null
|
||||
userName: string | null
|
||||
scheduleId: string | null
|
||||
scheduleName: string | null
|
||||
escalationPolicyId: string | null
|
||||
startTime: string | null
|
||||
endTime: string | null
|
||||
}
|
||||
|
||||
export interface RootlyListOnCallsResponse extends ToolResponse {
|
||||
output: {
|
||||
onCalls: RootlyOnCallData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** List Schedules */
|
||||
export interface RootlyListSchedulesParams extends RootlyBaseParams {
|
||||
search?: string
|
||||
pageSize?: number
|
||||
pageNumber?: number
|
||||
}
|
||||
|
||||
export interface RootlyScheduleData {
|
||||
id: string | null
|
||||
name: string
|
||||
description: string | null
|
||||
allTimeCoverage: boolean | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface RootlyListSchedulesResponse extends ToolResponse {
|
||||
output: {
|
||||
schedules: RootlyScheduleData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** List Escalation Policies */
|
||||
export interface RootlyListEscalationPoliciesParams extends RootlyBaseParams {
|
||||
search?: string
|
||||
pageSize?: number
|
||||
pageNumber?: number
|
||||
}
|
||||
|
||||
export interface RootlyEscalationPolicyData {
|
||||
id: string | null
|
||||
name: string
|
||||
description: string | null
|
||||
repeatCount: number | null
|
||||
groupIds: string[] | null
|
||||
serviceIds: string[] | null
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface RootlyListEscalationPoliciesResponse extends ToolResponse {
|
||||
output: {
|
||||
escalationPolicies: RootlyEscalationPolicyData[]
|
||||
totalCount: number
|
||||
}
|
||||
}
|
||||
|
||||
/** Union of all responses */
|
||||
export type RootlyResponse =
|
||||
| RootlyCreateIncidentResponse
|
||||
| RootlyGetIncidentResponse
|
||||
| RootlyUpdateIncidentResponse
|
||||
| RootlyDeleteIncidentResponse
|
||||
| RootlyListIncidentsResponse
|
||||
| RootlyCreateAlertResponse
|
||||
| RootlyGetAlertResponse
|
||||
| RootlyUpdateAlertResponse
|
||||
| RootlyAcknowledgeAlertResponse
|
||||
| RootlyResolveAlertResponse
|
||||
| RootlyListAlertsResponse
|
||||
| RootlyAddIncidentEventResponse
|
||||
| RootlyCreateActionItemResponse
|
||||
| RootlyListActionItemsResponse
|
||||
| RootlyListServicesResponse
|
||||
| RootlyListSeveritiesResponse
|
||||
| RootlyListRetrospectivesResponse
|
||||
@@ -363,3 +631,9 @@ export type RootlyResponse =
|
||||
| RootlyListEnvironmentsResponse
|
||||
| RootlyListIncidentTypesResponse
|
||||
| RootlyListFunctionalitiesResponse
|
||||
| RootlyListCausesResponse
|
||||
| RootlyListPlaybooksResponse
|
||||
| RootlyListUsersResponse
|
||||
| RootlyListOnCallsResponse
|
||||
| RootlyListSchedulesResponse
|
||||
| RootlyListEscalationPoliciesResponse
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
import type { RootlyUpdateAlertParams, RootlyUpdateAlertResponse } from '@/tools/rootly/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const rootlyUpdateAlertTool: ToolConfig<RootlyUpdateAlertParams, RootlyUpdateAlertResponse> =
|
||||
{
|
||||
id: 'rootly_update_alert',
|
||||
name: 'Rootly Update Alert',
|
||||
description: 'Update an existing alert in Rootly.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Rootly API key',
|
||||
},
|
||||
alertId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the alert to update',
|
||||
},
|
||||
summary: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated alert summary',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated alert description',
|
||||
},
|
||||
source: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated alert source',
|
||||
},
|
||||
serviceIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated service IDs to attach',
|
||||
},
|
||||
groupIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated team/group IDs to attach',
|
||||
},
|
||||
environmentIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated environment IDs to attach',
|
||||
},
|
||||
externalId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated external ID',
|
||||
},
|
||||
externalUrl: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated external URL',
|
||||
},
|
||||
deduplicationKey: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated deduplication key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.rootly.com/v1/alerts/${params.alertId.trim()}`,
|
||||
method: 'PATCH',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/vnd.api+json',
|
||||
Authorization: `Bearer ${params.apiKey}`,
|
||||
}),
|
||||
body: (params) => {
|
||||
const attributes: Record<string, unknown> = {}
|
||||
if (params.summary) attributes.summary = params.summary
|
||||
if (params.description) attributes.description = params.description
|
||||
if (params.source) attributes.source = params.source
|
||||
if (params.externalId) attributes.external_id = params.externalId
|
||||
if (params.externalUrl) attributes.external_url = params.externalUrl
|
||||
if (params.deduplicationKey) attributes.deduplication_key = params.deduplicationKey
|
||||
if (params.serviceIds) {
|
||||
attributes.service_ids = params.serviceIds.split(',').map((s: string) => s.trim())
|
||||
}
|
||||
if (params.groupIds) {
|
||||
attributes.group_ids = params.groupIds.split(',').map((s: string) => s.trim())
|
||||
}
|
||||
if (params.environmentIds) {
|
||||
attributes.environment_ids = params.environmentIds.split(',').map((s: string) => s.trim())
|
||||
}
|
||||
return { data: { type: 'alerts', id: params.alertId.trim(), attributes } }
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
return {
|
||||
success: false,
|
||||
output: { alert: {} as RootlyUpdateAlertResponse['output']['alert'] },
|
||||
error: errorData.errors?.[0]?.detail || `HTTP ${response.status}: ${response.statusText}`,
|
||||
}
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
const attrs = data.data?.attributes || {}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
alert: {
|
||||
id: data.data?.id ?? null,
|
||||
shortId: attrs.short_id ?? null,
|
||||
summary: attrs.summary ?? '',
|
||||
description: attrs.description ?? null,
|
||||
source: attrs.source ?? null,
|
||||
status: attrs.status ?? null,
|
||||
externalId: attrs.external_id ?? null,
|
||||
externalUrl: attrs.external_url ?? null,
|
||||
deduplicationKey: attrs.deduplication_key ?? null,
|
||||
createdAt: attrs.created_at ?? '',
|
||||
updatedAt: attrs.updated_at ?? '',
|
||||
startedAt: attrs.started_at ?? null,
|
||||
endedAt: attrs.ended_at ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
alert: {
|
||||
type: 'object',
|
||||
description: 'The updated alert',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique alert ID' },
|
||||
shortId: { type: 'string', description: 'Short alert ID' },
|
||||
summary: { type: 'string', description: 'Alert summary' },
|
||||
description: { type: 'string', description: 'Alert description' },
|
||||
source: { type: 'string', description: 'Alert source' },
|
||||
status: { type: 'string', description: 'Alert status' },
|
||||
externalId: { type: 'string', description: 'External ID' },
|
||||
externalUrl: { type: 'string', description: 'External URL' },
|
||||
deduplicationKey: { type: 'string', description: 'Deduplication key' },
|
||||
createdAt: { type: 'string', description: 'Creation date' },
|
||||
updatedAt: { type: 'string', description: 'Last update date' },
|
||||
startedAt: { type: 'string', description: 'Start date' },
|
||||
endedAt: { type: 'string', description: 'End date' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user