chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,130 @@
import type {
CloudWatchDescribeAlarmHistoryParams,
CloudWatchDescribeAlarmHistoryResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const describeAlarmHistoryTool: ToolConfig<
CloudWatchDescribeAlarmHistoryParams,
CloudWatchDescribeAlarmHistoryResponse
> = {
id: 'cloudwatch_describe_alarm_history',
name: 'CloudWatch Describe Alarm History',
description: 'Retrieve state-change and configuration history for CloudWatch alarms',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
alarmName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Name of a specific alarm to retrieve history for. Omit for all alarms.',
},
historyItemType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Filter by history item type (ConfigurationUpdate, StateUpdate, Action, AlarmContributorStateUpdate, AlarmContributorAction)',
},
startDate: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Start of the history window as Unix epoch seconds',
},
endDate: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'End of the history window as Unix epoch seconds',
},
scanBy: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Sort order: TimestampDescending (newest first) or TimestampAscending',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of history records to return',
},
},
request: {
url: '/api/tools/cloudwatch/describe-alarm-history',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
...(params.alarmName && { alarmName: params.alarmName }),
...(params.historyItemType && { historyItemType: params.historyItemType }),
...(params.startDate !== undefined && { startDate: params.startDate }),
...(params.endDate !== undefined && { endDate: params.endDate }),
...(params.scanBy && { scanBy: params.scanBy }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to describe CloudWatch alarm history')
}
return {
success: true,
output: {
alarmHistoryItems: data.output.alarmHistoryItems,
},
}
},
outputs: {
alarmHistoryItems: {
type: 'array',
description: 'Alarm history items sorted per scanBy, newest first by default',
items: {
type: 'object',
properties: {
alarmName: {
type: 'string',
description: 'Name of the alarm this history item belongs to',
},
alarmType: { type: 'string', description: 'MetricAlarm or CompositeAlarm' },
timestamp: { type: 'number', description: 'Epoch ms when the history item occurred' },
historyItemType: {
type: 'string',
description: 'ConfigurationUpdate, StateUpdate, Action, or contributor variants',
},
historySummary: { type: 'string', description: 'Human-readable summary of the event' },
},
},
},
},
}
@@ -0,0 +1,118 @@
import type {
CloudWatchDescribeAlarmsParams,
CloudWatchDescribeAlarmsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const describeAlarmsTool: ToolConfig<
CloudWatchDescribeAlarmsParams,
CloudWatchDescribeAlarmsResponse
> = {
id: 'cloudwatch_describe_alarms',
name: 'CloudWatch Describe Alarms',
description: 'List and filter CloudWatch alarms',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
alarmNamePrefix: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter alarms by name prefix',
},
stateValue: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by alarm state (OK, ALARM, INSUFFICIENT_DATA)',
},
alarmType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by alarm type (MetricAlarm, CompositeAlarm)',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of alarms to return',
},
},
request: {
url: '/api/tools/cloudwatch/describe-alarms',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
...(params.alarmNamePrefix && { alarmNamePrefix: params.alarmNamePrefix }),
...(params.stateValue && { stateValue: params.stateValue }),
...(params.alarmType && { alarmType: params.alarmType }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to describe CloudWatch alarms')
}
return {
success: true,
output: {
alarms: data.output.alarms,
},
}
},
outputs: {
alarms: {
type: 'array',
description: 'List of CloudWatch alarms with state and configuration',
items: {
type: 'object',
properties: {
alarmName: { type: 'string', description: 'Alarm name' },
alarmArn: { type: 'string', description: 'Alarm ARN' },
stateValue: {
type: 'string',
description: 'Current state (OK, ALARM, INSUFFICIENT_DATA)',
},
stateReason: { type: 'string', description: 'Human-readable reason for the state' },
metricName: { type: 'string', description: 'Metric name (MetricAlarm only)' },
namespace: { type: 'string', description: 'Metric namespace (MetricAlarm only)' },
threshold: { type: 'number', description: 'Threshold value (MetricAlarm only)' },
stateUpdatedTimestamp: {
type: 'number',
description: 'Epoch ms when state last changed',
},
},
},
},
},
}
@@ -0,0 +1,95 @@
import type {
CloudWatchDescribeLogGroupsParams,
CloudWatchDescribeLogGroupsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const describeLogGroupsTool: ToolConfig<
CloudWatchDescribeLogGroupsParams,
CloudWatchDescribeLogGroupsResponse
> = {
id: 'cloudwatch_describe_log_groups',
name: 'CloudWatch Describe Log Groups',
description: 'List available CloudWatch log groups',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
prefix: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter log groups by name prefix',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of log groups to return',
},
},
request: {
url: '/api/tools/cloudwatch/describe-log-groups',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
...(params.prefix && { prefix: params.prefix }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to describe CloudWatch log groups')
}
return {
success: true,
output: {
logGroups: data.output.logGroups,
},
}
},
outputs: {
logGroups: {
type: 'array',
description: 'List of CloudWatch log groups with metadata',
items: {
type: 'object',
properties: {
logGroupName: { type: 'string', description: 'Log group name' },
arn: { type: 'string', description: 'Log group ARN' },
storedBytes: { type: 'number', description: 'Total stored bytes' },
retentionInDays: { type: 'number', description: 'Retention period in days (if set)' },
creationTime: { type: 'number', description: 'Creation time in epoch milliseconds' },
},
},
},
},
}
@@ -0,0 +1,112 @@
import type {
CloudWatchDescribeLogStreamsParams,
CloudWatchDescribeLogStreamsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const describeLogStreamsTool: ToolConfig<
CloudWatchDescribeLogStreamsParams,
CloudWatchDescribeLogStreamsResponse
> = {
id: 'cloudwatch_describe_log_streams',
name: 'CloudWatch Describe Log Streams',
description: 'List log streams within a CloudWatch log group',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
logGroupName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'CloudWatch log group name',
},
prefix: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter log streams by name prefix',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of log streams to return',
},
},
request: {
url: '/api/tools/cloudwatch/describe-log-streams',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
logGroupName: params.logGroupName,
...(params.prefix && { prefix: params.prefix }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to describe CloudWatch log streams')
}
return {
success: true,
output: {
logStreams: data.output.logStreams,
},
}
},
outputs: {
logStreams: {
type: 'array',
description:
'List of log streams with metadata, sorted by last event time (most recent first) unless a prefix filter is applied',
items: {
type: 'object',
properties: {
logStreamName: { type: 'string', description: 'Log stream name' },
lastEventTimestamp: {
type: 'number',
description: 'Timestamp of the last log event in epoch milliseconds',
},
firstEventTimestamp: {
type: 'number',
description: 'Timestamp of the first log event in epoch milliseconds',
},
creationTime: {
type: 'number',
description: 'Stream creation time in epoch milliseconds',
},
storedBytes: { type: 'number', description: 'Total stored bytes' },
},
},
},
},
}
@@ -0,0 +1,131 @@
import type {
CloudWatchFilterLogEventsParams,
CloudWatchFilterLogEventsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const filterLogEventsTool: ToolConfig<
CloudWatchFilterLogEventsParams,
CloudWatchFilterLogEventsResponse
> = {
id: 'cloudwatch_filter_log_events',
name: 'CloudWatch Filter Log Events',
description:
'Search log events across all streams in a log group by filter pattern and time range, without writing a Log Insights query',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
logGroupName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'CloudWatch log group name to search',
},
filterPattern: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'CloudWatch Logs filter pattern (e.g., "ERROR", "?ERROR ?Exception"). Matches all events if omitted.',
},
logStreamNamePrefix: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Only search log streams whose name starts with this prefix',
},
startTime: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Start time as Unix epoch seconds',
},
endTime: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'End time as Unix epoch seconds',
},
startFromHead: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Return the earliest matching events first instead of the latest',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of events to return',
},
},
request: {
url: '/api/tools/cloudwatch/filter-log-events',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
logGroupName: params.logGroupName,
...(params.filterPattern && { filterPattern: params.filterPattern }),
...(params.logStreamNamePrefix && { logStreamNamePrefix: params.logStreamNamePrefix }),
...(params.startTime !== undefined && { startTime: params.startTime }),
...(params.endTime !== undefined && { endTime: params.endTime }),
...(params.startFromHead !== undefined && { startFromHead: params.startFromHead }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to filter CloudWatch log events')
}
return {
success: true,
output: {
events: data.output.events,
},
}
},
outputs: {
events: {
type: 'array',
description: 'Matching log events across all searched streams, sorted by timestamp',
items: {
type: 'object',
properties: {
logStreamName: { type: 'string', description: 'Log stream the event belongs to' },
timestamp: { type: 'number', description: 'Event timestamp in epoch milliseconds' },
message: { type: 'string', description: 'Log event message' },
ingestionTime: { type: 'number', description: 'Ingestion time in epoch milliseconds' },
},
},
},
},
}
+114
View File
@@ -0,0 +1,114 @@
import type {
CloudWatchGetLogEventsParams,
CloudWatchGetLogEventsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const getLogEventsTool: ToolConfig<
CloudWatchGetLogEventsParams,
CloudWatchGetLogEventsResponse
> = {
id: 'cloudwatch_get_log_events',
name: 'CloudWatch Get Log Events',
description: 'Retrieve log events from a specific CloudWatch log stream',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
logGroupName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'CloudWatch log group name',
},
logStreamName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'CloudWatch log stream name',
},
startTime: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Start time as Unix epoch seconds',
},
endTime: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'End time as Unix epoch seconds',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of events to return',
},
},
request: {
url: '/api/tools/cloudwatch/get-log-events',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
logGroupName: params.logGroupName,
logStreamName: params.logStreamName,
...(params.startTime !== undefined && { startTime: params.startTime }),
...(params.endTime !== undefined && { endTime: params.endTime }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get CloudWatch log events')
}
return {
success: true,
output: {
events: data.output.events,
},
}
},
outputs: {
events: {
type: 'array',
description: 'Log events with timestamp, message, and ingestion time',
items: {
type: 'object',
properties: {
timestamp: { type: 'number', description: 'Event timestamp in epoch milliseconds' },
message: { type: 'string', description: 'Log event message' },
ingestionTime: { type: 'number', description: 'Ingestion time in epoch milliseconds' },
},
},
},
},
}
@@ -0,0 +1,134 @@
import type {
CloudWatchGetMetricStatisticsParams,
CloudWatchGetMetricStatisticsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const getMetricStatisticsTool: ToolConfig<
CloudWatchGetMetricStatisticsParams,
CloudWatchGetMetricStatisticsResponse
> = {
id: 'cloudwatch_get_metric_statistics',
name: 'CloudWatch Get Metric Statistics',
description: 'Get statistics for a CloudWatch metric over a time range',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
namespace: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Metric namespace (e.g., AWS/EC2, AWS/Lambda)',
},
metricName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Metric name (e.g., CPUUtilization, Invocations)',
},
startTime: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Start time as Unix epoch seconds',
},
endTime: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'End time as Unix epoch seconds',
},
period: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Granularity in seconds (e.g., 60, 300, 3600)',
},
statistics: {
type: 'array',
required: true,
visibility: 'user-or-llm',
description: 'Statistics to retrieve (Average, Sum, Minimum, Maximum, SampleCount)',
},
dimensions: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Dimensions as JSON (e.g., {"InstanceId": "i-1234"})',
},
},
request: {
url: '/api/tools/cloudwatch/get-metric-statistics',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
namespace: params.namespace,
metricName: params.metricName,
startTime: params.startTime,
endTime: params.endTime,
period: params.period,
statistics: params.statistics,
...(params.dimensions && { dimensions: params.dimensions }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to get CloudWatch metric statistics')
}
return {
success: true,
output: {
label: data.output.label,
datapoints: data.output.datapoints,
},
}
},
outputs: {
label: { type: 'string', description: 'Metric label returned by CloudWatch' },
datapoints: {
type: 'array',
description: 'Datapoints sorted by timestamp with statistics values',
items: {
type: 'object',
properties: {
timestamp: { type: 'number', description: 'Datapoint timestamp in epoch milliseconds' },
average: { type: 'number', description: 'Average statistic value' },
sum: { type: 'number', description: 'Sum statistic value' },
minimum: { type: 'number', description: 'Minimum statistic value' },
maximum: { type: 'number', description: 'Maximum statistic value' },
sampleCount: { type: 'number', description: 'Sample count statistic value' },
unit: { type: 'string', description: 'Unit of the metric' },
},
},
},
},
}
+29
View File
@@ -0,0 +1,29 @@
import { describeAlarmHistoryTool } from '@/tools/cloudwatch/describe_alarm_history'
import { describeAlarmsTool } from '@/tools/cloudwatch/describe_alarms'
import { describeLogGroupsTool } from '@/tools/cloudwatch/describe_log_groups'
import { describeLogStreamsTool } from '@/tools/cloudwatch/describe_log_streams'
import { filterLogEventsTool } from '@/tools/cloudwatch/filter_log_events'
import { getLogEventsTool } from '@/tools/cloudwatch/get_log_events'
import { getMetricStatisticsTool } from '@/tools/cloudwatch/get_metric_statistics'
import { listMetricsTool } from '@/tools/cloudwatch/list_metrics'
import { muteAlarmTool } from '@/tools/cloudwatch/mute_alarm'
import { putLogGroupRetentionTool } from '@/tools/cloudwatch/put_log_group_retention'
import { putMetricDataTool } from '@/tools/cloudwatch/put_metric_data'
import { queryLogsTool } from '@/tools/cloudwatch/query_logs'
import { unmuteAlarmTool } from '@/tools/cloudwatch/unmute_alarm'
export * from './types'
export const cloudwatchDescribeAlarmHistoryTool = describeAlarmHistoryTool
export const cloudwatchDescribeAlarmsTool = describeAlarmsTool
export const cloudwatchDescribeLogGroupsTool = describeLogGroupsTool
export const cloudwatchDescribeLogStreamsTool = describeLogStreamsTool
export const cloudwatchFilterLogEventsTool = filterLogEventsTool
export const cloudwatchGetLogEventsTool = getLogEventsTool
export const cloudwatchGetMetricStatisticsTool = getMetricStatisticsTool
export const cloudwatchListMetricsTool = listMetricsTool
export const cloudwatchMuteAlarmTool = muteAlarmTool
export const cloudwatchPutLogGroupRetentionTool = putLogGroupRetentionTool
export const cloudwatchPutMetricDataTool = putMetricDataTool
export const cloudwatchQueryLogsTool = queryLogsTool
export const cloudwatchUnmuteAlarmTool = unmuteAlarmTool
+107
View File
@@ -0,0 +1,107 @@
import type {
CloudWatchListMetricsParams,
CloudWatchListMetricsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const listMetricsTool: ToolConfig<
CloudWatchListMetricsParams,
CloudWatchListMetricsResponse
> = {
id: 'cloudwatch_list_metrics',
name: 'CloudWatch List Metrics',
description: 'List available CloudWatch metrics',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
namespace: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by namespace (e.g., AWS/EC2, AWS/Lambda)',
},
metricName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by metric name',
},
recentlyActive: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Only show metrics active in the last 3 hours',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of metrics to return',
},
},
request: {
url: '/api/tools/cloudwatch/list-metrics',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
...(params.namespace && { namespace: params.namespace }),
...(params.metricName && { metricName: params.metricName }),
...(params.recentlyActive && { recentlyActive: params.recentlyActive }),
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to list CloudWatch metrics')
}
return {
success: true,
output: {
metrics: data.output.metrics,
},
}
},
outputs: {
metrics: {
type: 'array',
description: 'List of metrics with namespace, name, and dimensions',
items: {
type: 'object',
properties: {
namespace: { type: 'string', description: 'Metric namespace (e.g., AWS/EC2)' },
metricName: { type: 'string', description: 'Metric name (e.g., CPUUtilization)' },
dimensions: { type: 'array', description: 'Array of name/value dimension pairs' },
},
},
},
},
}
+114
View File
@@ -0,0 +1,114 @@
import type {
CloudWatchMuteAlarmParams,
CloudWatchMuteAlarmResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const muteAlarmTool: ToolConfig<CloudWatchMuteAlarmParams, CloudWatchMuteAlarmResponse> = {
id: 'cloudwatch_mute_alarm',
name: 'CloudWatch Mute Alarm',
description: 'Create a CloudWatch alarm mute rule that suppresses alarms for a fixed duration',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
muteRuleName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique name for the mute rule (used later to unmute)',
},
alarmNames: {
type: 'array',
required: true,
visibility: 'user-or-llm',
description: 'Names of the CloudWatch alarms this mute rule targets',
},
durationValue: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'How long the mute lasts (paired with durationUnit)',
},
durationUnit: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unit for durationValue: minutes, hours, or days',
},
description: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Optional description of why the alarms are being muted',
},
startDate: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description:
'When the mute window begins as Unix epoch seconds. Defaults to now (mute starts immediately).',
},
},
request: {
url: '/api/tools/cloudwatch/mute-alarm',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
muteRuleName: params.muteRuleName,
alarmNames: params.alarmNames,
durationValue: params.durationValue,
durationUnit: params.durationUnit,
...(params.description && { description: params.description }),
...(params.startDate !== undefined && { startDate: params.startDate }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to create CloudWatch alarm mute rule')
}
return {
success: true,
output: data.output,
}
},
outputs: {
success: { type: 'boolean', description: 'Whether the mute rule was created successfully' },
muteRuleName: { type: 'string', description: 'Name of the mute rule that was created' },
alarmNames: {
type: 'array',
description: 'Names of the alarms this rule mutes',
items: { type: 'string' },
},
expression: { type: 'string', description: 'Schedule expression used by the mute rule' },
duration: { type: 'string', description: 'ISO 8601 duration of the mute window' },
},
}
@@ -0,0 +1,87 @@
import type {
CloudWatchPutLogGroupRetentionParams,
CloudWatchPutLogGroupRetentionResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const putLogGroupRetentionTool: ToolConfig<
CloudWatchPutLogGroupRetentionParams,
CloudWatchPutLogGroupRetentionResponse
> = {
id: 'cloudwatch_put_log_group_retention',
name: 'CloudWatch Set Log Group Retention',
description: 'Set (or clear, for never-expire) the retention period for a CloudWatch log group',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
logGroupName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'CloudWatch log group name',
},
retentionInDays: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description:
'Days to retain log events (one of 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653). Omit to make events never expire.',
},
},
request: {
url: '/api/tools/cloudwatch/put-log-group-retention',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
logGroupName: params.logGroupName,
...(params.retentionInDays !== undefined && { retentionInDays: params.retentionInDays }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to set CloudWatch log group retention')
}
return {
success: true,
output: data.output,
}
},
outputs: {
success: { type: 'boolean', description: 'Whether the retention policy was updated' },
logGroupName: { type: 'string', description: 'Log group the policy applies to' },
retentionInDays: {
type: 'number',
description: 'Retention period in days, or null if events never expire',
optional: true,
},
},
}
@@ -0,0 +1,106 @@
import type {
CloudWatchPutMetricDataParams,
CloudWatchPutMetricDataResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const putMetricDataTool: ToolConfig<
CloudWatchPutMetricDataParams,
CloudWatchPutMetricDataResponse
> = {
id: 'cloudwatch_put_metric_data',
name: 'CloudWatch Publish Metric',
description: 'Publish a custom metric data point to CloudWatch',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
namespace: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Metric namespace (e.g., Custom/MyApp)',
},
metricName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name of the metric',
},
value: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Metric value to publish',
},
unit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Unit of the metric (e.g., Count, Seconds, Bytes)',
},
dimensions: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'JSON string of dimension name/value pairs',
},
},
request: {
url: '/api/tools/cloudwatch/put-metric-data',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
namespace: params.namespace,
metricName: params.metricName,
value: params.value,
...(params.unit && { unit: params.unit }),
...(params.dimensions && { dimensions: params.dimensions }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to publish CloudWatch metric')
}
return {
success: true,
output: data.output,
}
},
outputs: {
success: { type: 'boolean', description: 'Whether the metric was published successfully' },
namespace: { type: 'string', description: 'Metric namespace' },
metricName: { type: 'string', description: 'Metric name' },
value: { type: 'number', description: 'Published metric value' },
unit: { type: 'string', description: 'Metric unit' },
timestamp: { type: 'string', description: 'Timestamp when the metric was published' },
},
}
+121
View File
@@ -0,0 +1,121 @@
import type {
CloudWatchQueryLogsParams,
CloudWatchQueryLogsResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const queryLogsTool: ToolConfig<CloudWatchQueryLogsParams, CloudWatchQueryLogsResponse> = {
id: 'cloudwatch_query_logs',
name: 'CloudWatch Query Logs',
description: 'Run a CloudWatch Log Insights query against one or more log groups',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
logGroupNames: {
type: 'array',
required: true,
visibility: 'user-or-llm',
description: 'Log group names to query',
},
queryString: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'CloudWatch Log Insights query string',
},
startTime: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Start time as Unix epoch seconds',
},
endTime: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'End time as Unix epoch seconds',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of results to return',
},
},
request: {
url: '/api/tools/cloudwatch/query-logs',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
logGroupNames: params.logGroupNames,
queryString: params.queryString,
startTime: params.startTime,
endTime: params.endTime,
...(params.limit !== undefined && { limit: params.limit }),
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'CloudWatch Log Insights query failed')
}
return {
success: true,
output: {
results: data.output.results,
statistics: data.output.statistics,
status: data.output.status,
},
}
},
outputs: {
results: {
type: 'array',
description: 'Query result rows (each row is a key/value map of field name to value)',
},
statistics: {
type: 'object',
description: 'Query statistics',
properties: {
bytesScanned: { type: 'number', description: 'Total bytes of log data scanned' },
recordsMatched: {
type: 'number',
description: 'Number of log records that matched the query',
},
recordsScanned: { type: 'number', description: 'Total log records scanned' },
},
},
status: {
type: 'string',
description: 'Query completion status (Complete, Failed, Cancelled, or Timeout)',
},
},
}
+261
View File
@@ -0,0 +1,261 @@
import type { ToolResponse } from '@/tools/types'
interface CloudWatchConnectionConfig {
awsRegion: string
awsAccessKeyId: string
awsSecretAccessKey: string
}
export interface CloudWatchQueryLogsParams extends CloudWatchConnectionConfig {
logGroupNames: string[]
queryString: string
startTime: number
endTime: number
limit?: number
}
export interface CloudWatchDescribeLogGroupsParams extends CloudWatchConnectionConfig {
prefix?: string
limit?: number
}
export interface CloudWatchGetLogEventsParams extends CloudWatchConnectionConfig {
logGroupName: string
logStreamName: string
startTime?: number
endTime?: number
limit?: number
}
export interface CloudWatchQueryLogsResponse extends ToolResponse {
output: {
results: Record<string, string>[]
statistics: {
bytesScanned: number
recordsMatched: number
recordsScanned: number
}
status: string
}
}
export interface CloudWatchDescribeLogGroupsResponse extends ToolResponse {
output: {
logGroups: {
logGroupName: string
arn: string
storedBytes: number
retentionInDays: number | undefined
creationTime: number | undefined
}[]
}
}
export interface CloudWatchGetLogEventsResponse extends ToolResponse {
output: {
events: {
timestamp: number | undefined
message: string | undefined
ingestionTime: number | undefined
}[]
}
}
export interface CloudWatchDescribeLogStreamsParams extends CloudWatchConnectionConfig {
logGroupName: string
prefix?: string
limit?: number
}
export interface CloudWatchDescribeLogStreamsResponse extends ToolResponse {
output: {
logStreams: {
logStreamName: string
lastEventTimestamp: number | undefined
firstEventTimestamp: number | undefined
creationTime: number | undefined
storedBytes: number
}[]
}
}
export interface CloudWatchListMetricsParams extends CloudWatchConnectionConfig {
namespace?: string
metricName?: string
recentlyActive?: boolean
limit?: number
}
export interface CloudWatchListMetricsResponse extends ToolResponse {
output: {
metrics: {
namespace: string
metricName: string
dimensions: { name: string; value: string }[]
}[]
}
}
export interface CloudWatchGetMetricStatisticsParams extends CloudWatchConnectionConfig {
namespace: string
metricName: string
startTime: number
endTime: number
period: number
statistics: string[]
dimensions?: string
}
export interface CloudWatchGetMetricStatisticsResponse extends ToolResponse {
output: {
label: string
datapoints: {
timestamp: number
average?: number
sum?: number
minimum?: number
maximum?: number
sampleCount?: number
unit?: string
}[]
}
}
export interface CloudWatchDescribeAlarmsParams extends CloudWatchConnectionConfig {
alarmNamePrefix?: string
stateValue?: string
alarmType?: string
limit?: number
}
export interface CloudWatchDescribeAlarmsResponse extends ToolResponse {
output: {
alarms: {
alarmName: string
alarmArn: string
stateValue: string
stateReason: string
metricName: string | undefined
namespace: string | undefined
comparisonOperator: string | undefined
threshold: number | undefined
evaluationPeriods: number | undefined
stateUpdatedTimestamp: number | undefined
}[]
}
}
export interface CloudWatchPutMetricDataParams extends CloudWatchConnectionConfig {
namespace: string
metricName: string
value: number
unit?: string
dimensions?: string
}
export interface CloudWatchPutMetricDataResponse extends ToolResponse {
output: {
success: boolean
namespace: string
metricName: string
value: number
unit: string
timestamp: string
}
}
export type CloudWatchMuteDurationUnit = 'minutes' | 'hours' | 'days'
export interface CloudWatchMuteAlarmParams extends CloudWatchConnectionConfig {
muteRuleName: string
alarmNames: string[]
durationValue: number
durationUnit: CloudWatchMuteDurationUnit
description?: string
startDate?: number
}
export interface CloudWatchMuteAlarmResponse extends ToolResponse {
output: {
success: boolean
muteRuleName: string
alarmNames: string[]
expression: string
duration: string
}
}
export interface CloudWatchUnmuteAlarmParams extends CloudWatchConnectionConfig {
muteRuleName: string
}
export interface CloudWatchUnmuteAlarmResponse extends ToolResponse {
output: {
success: boolean
muteRuleName: string
}
}
export type CloudWatchAlarmHistoryItemType =
| 'ConfigurationUpdate'
| 'StateUpdate'
| 'Action'
| 'AlarmContributorStateUpdate'
| 'AlarmContributorAction'
export type CloudWatchAlarmHistoryScanBy = 'TimestampDescending' | 'TimestampAscending'
export interface CloudWatchDescribeAlarmHistoryParams extends CloudWatchConnectionConfig {
alarmName?: string
historyItemType?: CloudWatchAlarmHistoryItemType
startDate?: number
endDate?: number
scanBy?: CloudWatchAlarmHistoryScanBy
limit?: number
}
export interface CloudWatchDescribeAlarmHistoryResponse extends ToolResponse {
output: {
alarmHistoryItems: {
alarmName: string | undefined
alarmType: string | undefined
timestamp: number | undefined
historyItemType: string | undefined
historySummary: string | undefined
}[]
}
}
export interface CloudWatchFilterLogEventsParams extends CloudWatchConnectionConfig {
logGroupName: string
filterPattern?: string
logStreamNamePrefix?: string
startTime?: number
endTime?: number
startFromHead?: boolean
limit?: number
}
export interface CloudWatchFilterLogEventsResponse extends ToolResponse {
output: {
events: {
logStreamName: string | undefined
timestamp: number | undefined
message: string | undefined
ingestionTime: number | undefined
}[]
}
}
export interface CloudWatchPutLogGroupRetentionParams extends CloudWatchConnectionConfig {
logGroupName: string
retentionInDays?: number
}
export interface CloudWatchPutLogGroupRetentionResponse extends ToolResponse {
output: {
success: boolean
logGroupName: string
retentionInDays: number | null
}
}
+74
View File
@@ -0,0 +1,74 @@
import type {
CloudWatchUnmuteAlarmParams,
CloudWatchUnmuteAlarmResponse,
} from '@/tools/cloudwatch/types'
import type { ToolConfig } from '@/tools/types'
export const unmuteAlarmTool: ToolConfig<
CloudWatchUnmuteAlarmParams,
CloudWatchUnmuteAlarmResponse
> = {
id: 'cloudwatch_unmute_alarm',
name: 'CloudWatch Unmute Alarm',
description: 'Delete a CloudWatch alarm mute rule, restoring alarm notifications',
version: '1.0.0',
params: {
awsRegion: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS region (e.g., us-east-1)',
},
awsAccessKeyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS access key ID',
},
awsSecretAccessKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AWS secret access key',
},
muteRuleName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name of the mute rule to delete',
},
},
request: {
url: '/api/tools/cloudwatch/unmute-alarm',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params) => ({
region: params.awsRegion,
accessKeyId: params.awsAccessKeyId,
secretAccessKey: params.awsSecretAccessKey,
muteRuleName: params.muteRuleName,
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Failed to delete CloudWatch alarm mute rule')
}
return {
success: true,
output: data.output,
}
},
outputs: {
success: { type: 'boolean', description: 'Whether the mute rule was deleted successfully' },
muteRuleName: { type: 'string', description: 'Name of the mute rule that was deleted' },
},
}