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
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:
@@ -0,0 +1,131 @@
|
||||
import type {
|
||||
SESCreateConfigurationSetParams,
|
||||
SESCreateConfigurationSetResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const createConfigurationSetTool: ToolConfig<
|
||||
SESCreateConfigurationSetParams,
|
||||
SESCreateConfigurationSetResponse
|
||||
> = {
|
||||
id: 'ses_create_configuration_set',
|
||||
name: 'SES Create Configuration Set',
|
||||
description:
|
||||
'Create an SES configuration set to control tracking, delivery, reputation, sending, and suppression behavior for emails',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the configuration set (letters, numbers, hyphens, underscores)',
|
||||
},
|
||||
customRedirectDomain: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom domain to use for open/click tracking links',
|
||||
},
|
||||
httpsPolicy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'HTTPS policy for tracking links: REQUIRE, REQUIRE_OPEN_ONLY, or OPTIONAL',
|
||||
},
|
||||
tlsPolicy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether delivery requires TLS: REQUIRE or OPTIONAL',
|
||||
},
|
||||
sendingPoolName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Dedicated IP pool to associate with the configuration set',
|
||||
},
|
||||
reputationMetricsEnabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to collect reputation metrics for emails using this configuration set',
|
||||
},
|
||||
sendingEnabled: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether sending is enabled for this configuration set',
|
||||
},
|
||||
suppressedReasons: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated reasons that trigger suppression: BOUNCE, COMPLAINT',
|
||||
},
|
||||
tags: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'JSON array of tags to associate with the configuration set: [{"key":"","value":""}]',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/create-configuration-set',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
configurationSetName: params.configurationSetName,
|
||||
customRedirectDomain: params.customRedirectDomain,
|
||||
httpsPolicy: params.httpsPolicy,
|
||||
tlsPolicy: params.tlsPolicy,
|
||||
sendingPoolName: params.sendingPoolName,
|
||||
reputationMetricsEnabled: params.reputationMetricsEnabled,
|
||||
sendingEnabled: params.sendingEnabled,
|
||||
suppressedReasons: params.suppressedReasons,
|
||||
tags: params.tags,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to create configuration set')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import type {
|
||||
SESCreateEmailIdentityParams,
|
||||
SESCreateEmailIdentityResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const createEmailIdentityTool: ToolConfig<
|
||||
SESCreateEmailIdentityParams,
|
||||
SESCreateEmailIdentityResponse
|
||||
> = {
|
||||
id: 'ses_create_email_identity',
|
||||
name: 'SES Create Email Identity',
|
||||
description: 'Start verification of a new SES email address or domain identity',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailIdentity: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The email address or domain to verify',
|
||||
},
|
||||
dkimSigningAttributes: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Bring-your-own-DKIM signing attributes as JSON (domainSigningSelector, domainSigningPrivateKey, nextSigningKeyLength). Domain identities only.',
|
||||
},
|
||||
tags: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON array of tags to associate with the identity: [{"key":"","value":""}]',
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Default configuration set to use when sending from this identity',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/create-email-identity',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailIdentity: params.emailIdentity,
|
||||
dkimSigningAttributes: params.dkimSigningAttributes,
|
||||
tags: params.tags,
|
||||
configurationSetName: params.configurationSetName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to create email identity')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
identityType: data.identityType ?? '',
|
||||
verifiedForSendingStatus: data.verifiedForSendingStatus ?? false,
|
||||
dkimAttributes: data.dkimAttributes ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
identityType: { type: 'string', description: 'The identity type: EMAIL_ADDRESS or DOMAIN' },
|
||||
verifiedForSendingStatus: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the identity is verified and can send email',
|
||||
},
|
||||
dkimAttributes: {
|
||||
type: 'json',
|
||||
description: 'DKIM signing status and CNAME tokens for the identity',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import type { SESCreateTemplateParams, SESCreateTemplateResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const createTemplateTool: ToolConfig<SESCreateTemplateParams, SESCreateTemplateResponse> = {
|
||||
id: 'ses_create_template',
|
||||
name: 'SES Create Template',
|
||||
description: 'Create a new SES email template for use with templated email sending',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Unique name for the email template',
|
||||
},
|
||||
subjectPart: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Subject line template (supports {{variable}} substitution)',
|
||||
},
|
||||
textPart: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Plain text version of the template body',
|
||||
},
|
||||
htmlPart: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'HTML version of the template body',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/create-template',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
templateName: params.templateName,
|
||||
subjectPart: params.subjectPart,
|
||||
textPart: params.textPart,
|
||||
htmlPart: params.htmlPart,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to create template')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? 'Template created successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message for the created template' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import type {
|
||||
SESDeleteEmailIdentityParams,
|
||||
SESDeleteEmailIdentityResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const deleteEmailIdentityTool: ToolConfig<
|
||||
SESDeleteEmailIdentityParams,
|
||||
SESDeleteEmailIdentityResponse
|
||||
> = {
|
||||
id: 'ses_delete_email_identity',
|
||||
name: 'SES Delete Email Identity',
|
||||
description: 'Delete a verified SES email address or domain identity',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailIdentity: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The email address or domain identity to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/delete-email-identity',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailIdentity: params.emailIdentity,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to delete email identity')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import type {
|
||||
SESDeleteSuppressedDestinationParams,
|
||||
SESDeleteSuppressedDestinationResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const deleteSuppressedDestinationTool: ToolConfig<
|
||||
SESDeleteSuppressedDestinationParams,
|
||||
SESDeleteSuppressedDestinationResponse
|
||||
> = {
|
||||
id: 'ses_delete_suppressed_destination',
|
||||
name: 'SES Delete Suppressed Destination',
|
||||
description: 'Remove an email address from the account-level SES suppression list',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The email address to remove from the suppression list',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/delete-suppressed-destination',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailAddress: params.emailAddress,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to remove suppressed destination')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { SESDeleteTemplateParams, SESDeleteTemplateResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const deleteTemplateTool: ToolConfig<SESDeleteTemplateParams, SESDeleteTemplateResponse> = {
|
||||
id: 'ses_delete_template',
|
||||
name: 'SES Delete Template',
|
||||
description: 'Delete an existing SES email template',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the template to delete',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/delete-template',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
templateName: params.templateName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to delete template')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? 'Template deleted successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message for the deleted template' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import type { SESGetAccountParams, SESGetAccountResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getAccountTool: ToolConfig<SESGetAccountParams, SESGetAccountResponse> = {
|
||||
id: 'ses_get_account',
|
||||
name: 'SES Get Account',
|
||||
description: 'Get SES account sending quota and status information',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/get-account',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to get account information')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
sendingEnabled: data.sendingEnabled ?? false,
|
||||
max24HourSend: data.max24HourSend ?? 0,
|
||||
maxSendRate: data.maxSendRate ?? 0,
|
||||
sentLast24Hours: data.sentLast24Hours ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
sendingEnabled: {
|
||||
type: 'boolean',
|
||||
description: 'Whether email sending is enabled for the account',
|
||||
},
|
||||
max24HourSend: { type: 'number', description: 'Maximum emails allowed per 24-hour period' },
|
||||
maxSendRate: { type: 'number', description: 'Maximum emails allowed per second' },
|
||||
sentLast24Hours: { type: 'number', description: 'Number of emails sent in the last 24 hours' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import type { SESGetEmailIdentityParams, SESGetEmailIdentityResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getEmailIdentityTool: ToolConfig<
|
||||
SESGetEmailIdentityParams,
|
||||
SESGetEmailIdentityResponse
|
||||
> = {
|
||||
id: 'ses_get_email_identity',
|
||||
name: 'SES Get Email Identity',
|
||||
description:
|
||||
'Retrieve verification status, DKIM, Mail-From, and policy details for an SES identity',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailIdentity: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The email address or domain identity to look up',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/get-email-identity',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailIdentity: params.emailIdentity,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to get email identity')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
identityType: data.identityType ?? '',
|
||||
verifiedForSendingStatus: data.verifiedForSendingStatus ?? false,
|
||||
verificationStatus: data.verificationStatus ?? null,
|
||||
feedbackForwardingStatus: data.feedbackForwardingStatus ?? null,
|
||||
configurationSetName: data.configurationSetName ?? null,
|
||||
dkimAttributes: data.dkimAttributes ?? null,
|
||||
mailFromAttributes: data.mailFromAttributes ?? null,
|
||||
policies: data.policies ?? null,
|
||||
tags: data.tags ?? [],
|
||||
verificationInfo: data.verificationInfo ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
identityType: { type: 'string', description: 'The identity type: EMAIL_ADDRESS or DOMAIN' },
|
||||
verifiedForSendingStatus: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the identity is verified and can send email',
|
||||
},
|
||||
verificationStatus: {
|
||||
type: 'string',
|
||||
description: 'Verification status: PENDING, SUCCESS, FAILED, TEMPORARY_FAILURE, NOT_STARTED',
|
||||
optional: true,
|
||||
},
|
||||
feedbackForwardingStatus: {
|
||||
type: 'boolean',
|
||||
description: 'Whether bounce/complaint notifications are forwarded by email',
|
||||
optional: true,
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
description: 'Default configuration set for this identity',
|
||||
optional: true,
|
||||
},
|
||||
dkimAttributes: {
|
||||
type: 'json',
|
||||
description: 'DKIM signing status and CNAME tokens for the identity',
|
||||
optional: true,
|
||||
},
|
||||
mailFromAttributes: {
|
||||
type: 'json',
|
||||
description: 'Custom MAIL FROM domain configuration for the identity',
|
||||
optional: true,
|
||||
},
|
||||
policies: {
|
||||
type: 'json',
|
||||
description: 'Sending authorization policies attached to the identity',
|
||||
optional: true,
|
||||
},
|
||||
tags: { type: 'array', description: 'Tags associated with the identity' },
|
||||
verificationInfo: {
|
||||
type: 'json',
|
||||
description: 'Additional verification diagnostics (error type, last checked/success time)',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import type {
|
||||
SESGetSuppressedDestinationParams,
|
||||
SESGetSuppressedDestinationResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getSuppressedDestinationTool: ToolConfig<
|
||||
SESGetSuppressedDestinationParams,
|
||||
SESGetSuppressedDestinationResponse
|
||||
> = {
|
||||
id: 'ses_get_suppressed_destination',
|
||||
name: 'SES Get Suppressed Destination',
|
||||
description: 'Retrieve details for a specific email address on the SES suppression list',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The suppressed email address to look up',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/get-suppressed-destination',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailAddress: params.emailAddress,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to get suppressed destination')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
emailAddress: data.emailAddress ?? '',
|
||||
reason: data.reason ?? '',
|
||||
lastUpdateTime: data.lastUpdateTime ?? null,
|
||||
messageId: data.messageId ?? null,
|
||||
feedbackId: data.feedbackId ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
emailAddress: { type: 'string', description: 'The suppressed email address' },
|
||||
reason: { type: 'string', description: 'The reason the address is suppressed' },
|
||||
lastUpdateTime: {
|
||||
type: 'string',
|
||||
description: 'When the address was added to the suppression list',
|
||||
optional: true,
|
||||
},
|
||||
messageId: {
|
||||
type: 'string',
|
||||
description: 'The message ID associated with the bounce or complaint event',
|
||||
optional: true,
|
||||
},
|
||||
feedbackId: {
|
||||
type: 'string',
|
||||
description: 'The feedback ID associated with the bounce or complaint event',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import type { SESGetTemplateParams, SESGetTemplateResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const getTemplateTool: ToolConfig<SESGetTemplateParams, SESGetTemplateResponse> = {
|
||||
id: 'ses_get_template',
|
||||
name: 'SES Get Template',
|
||||
description: 'Retrieve the content and details of an SES email template',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the template to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/get-template',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
templateName: params.templateName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to get template')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
templateName: data.templateName ?? '',
|
||||
subjectPart: data.subjectPart ?? '',
|
||||
textPart: data.textPart ?? null,
|
||||
htmlPart: data.htmlPart ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
templateName: { type: 'string', description: 'Name of the template' },
|
||||
subjectPart: { type: 'string', description: 'Subject line of the template' },
|
||||
textPart: {
|
||||
type: 'string',
|
||||
description: 'Plain text body of the template',
|
||||
optional: true,
|
||||
},
|
||||
htmlPart: {
|
||||
type: 'string',
|
||||
description: 'HTML body of the template',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createConfigurationSetTool } from './create_configuration_set'
|
||||
import { createEmailIdentityTool } from './create_email_identity'
|
||||
import { createTemplateTool } from './create_template'
|
||||
import { deleteEmailIdentityTool } from './delete_email_identity'
|
||||
import { deleteSuppressedDestinationTool } from './delete_suppressed_destination'
|
||||
import { deleteTemplateTool } from './delete_template'
|
||||
import { getAccountTool } from './get_account'
|
||||
import { getEmailIdentityTool } from './get_email_identity'
|
||||
import { getSuppressedDestinationTool } from './get_suppressed_destination'
|
||||
import { getTemplateTool } from './get_template'
|
||||
import { listIdentitiesTool } from './list_identities'
|
||||
import { listSuppressedDestinationsTool } from './list_suppressed_destinations'
|
||||
import { listTemplatesTool } from './list_templates'
|
||||
import { putSuppressedDestinationTool } from './put_suppressed_destination'
|
||||
import { sendBulkEmailTool } from './send_bulk_email'
|
||||
import { sendCustomVerificationEmailTool } from './send_custom_verification_email'
|
||||
import { sendEmailTool } from './send_email'
|
||||
import { sendTemplatedEmailTool } from './send_templated_email'
|
||||
import { updateTemplateTool } from './update_template'
|
||||
|
||||
export const sesSendEmailTool = sendEmailTool
|
||||
export const sesSendTemplatedEmailTool = sendTemplatedEmailTool
|
||||
export const sesSendBulkEmailTool = sendBulkEmailTool
|
||||
export const sesListIdentitiesTool = listIdentitiesTool
|
||||
export const sesGetAccountTool = getAccountTool
|
||||
export const sesCreateTemplateTool = createTemplateTool
|
||||
export const sesGetTemplateTool = getTemplateTool
|
||||
export const sesListTemplatesTool = listTemplatesTool
|
||||
export const sesDeleteTemplateTool = deleteTemplateTool
|
||||
export const sesUpdateTemplateTool = updateTemplateTool
|
||||
export const sesPutSuppressedDestinationTool = putSuppressedDestinationTool
|
||||
export const sesDeleteSuppressedDestinationTool = deleteSuppressedDestinationTool
|
||||
export const sesGetSuppressedDestinationTool = getSuppressedDestinationTool
|
||||
export const sesListSuppressedDestinationsTool = listSuppressedDestinationsTool
|
||||
export const sesCreateEmailIdentityTool = createEmailIdentityTool
|
||||
export const sesDeleteEmailIdentityTool = deleteEmailIdentityTool
|
||||
export const sesGetEmailIdentityTool = getEmailIdentityTool
|
||||
export const sesCreateConfigurationSetTool = createConfigurationSetTool
|
||||
export const sesSendCustomVerificationEmailTool = sendCustomVerificationEmailTool
|
||||
|
||||
export * from './types'
|
||||
@@ -0,0 +1,87 @@
|
||||
import type { SESListIdentitiesParams, SESListIdentitiesResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listIdentitiesTool: ToolConfig<SESListIdentitiesParams, SESListIdentitiesResponse> = {
|
||||
id: 'ses_list_identities',
|
||||
name: 'SES List Identities',
|
||||
description:
|
||||
'List all verified email identities (email addresses and domains) in your SES account',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of identities to return (1-1000)',
|
||||
},
|
||||
nextToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination token from a previous list response',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/list-identities',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
pageSize: params.pageSize,
|
||||
nextToken: params.nextToken,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to list identities')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
identities: data.identities ?? [],
|
||||
nextToken: data.nextToken ?? null,
|
||||
count: data.count ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
identities: {
|
||||
type: 'array',
|
||||
description:
|
||||
'List of email identities with name, type, sending status, and verification status',
|
||||
},
|
||||
nextToken: {
|
||||
type: 'string',
|
||||
description: 'Pagination token for the next page of results',
|
||||
optional: true,
|
||||
},
|
||||
count: { type: 'number', description: 'Number of identities returned' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type {
|
||||
SESListSuppressedDestinationsParams,
|
||||
SESListSuppressedDestinationsResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listSuppressedDestinationsTool: ToolConfig<
|
||||
SESListSuppressedDestinationsParams,
|
||||
SESListSuppressedDestinationsResponse
|
||||
> = {
|
||||
id: 'ses_list_suppressed_destinations',
|
||||
name: 'SES List Suppressed Destinations',
|
||||
description: 'List email addresses on the account-level SES suppression list',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
reasons: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated suppression reasons to filter by: BOUNCE, COMPLAINT',
|
||||
},
|
||||
startDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Only include addresses suppressed after this ISO 8601 date',
|
||||
},
|
||||
endDate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Only include addresses suppressed before this ISO 8601 date',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of results to return',
|
||||
},
|
||||
nextToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination token from a previous list response',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/list-suppressed-destinations',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
reasons: params.reasons,
|
||||
startDate: params.startDate,
|
||||
endDate: params.endDate,
|
||||
pageSize: params.pageSize,
|
||||
nextToken: params.nextToken,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to list suppressed destinations')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
destinations: data.destinations ?? [],
|
||||
nextToken: data.nextToken ?? null,
|
||||
count: data.count ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
destinations: {
|
||||
type: 'array',
|
||||
description: 'List of suppressed destinations with email address, reason, and last update',
|
||||
},
|
||||
nextToken: {
|
||||
type: 'string',
|
||||
description: 'Pagination token for the next page of results',
|
||||
optional: true,
|
||||
},
|
||||
count: { type: 'number', description: 'Number of suppressed destinations returned' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import type { SESListTemplatesParams, SESListTemplatesResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listTemplatesTool: ToolConfig<SESListTemplatesParams, SESListTemplatesResponse> = {
|
||||
id: 'ses_list_templates',
|
||||
name: 'SES List Templates',
|
||||
description: 'List all SES email templates in your account',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of templates to return',
|
||||
},
|
||||
nextToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination token from a previous list response',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/list-templates',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
pageSize: params.pageSize,
|
||||
nextToken: params.nextToken,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to list templates')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
templates: data.templates ?? [],
|
||||
nextToken: data.nextToken ?? null,
|
||||
count: data.count ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
templates: {
|
||||
type: 'array',
|
||||
description: 'List of email templates with name and creation timestamp',
|
||||
},
|
||||
nextToken: {
|
||||
type: 'string',
|
||||
description: 'Pagination token for the next page of results',
|
||||
optional: true,
|
||||
},
|
||||
count: { type: 'number', description: 'Number of templates returned' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import type {
|
||||
SESPutSuppressedDestinationParams,
|
||||
SESPutSuppressedDestinationResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const putSuppressedDestinationTool: ToolConfig<
|
||||
SESPutSuppressedDestinationParams,
|
||||
SESPutSuppressedDestinationResponse
|
||||
> = {
|
||||
id: 'ses_put_suppressed_destination',
|
||||
name: 'SES Put Suppressed Destination',
|
||||
description: 'Add an email address to the account-level SES suppression list',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The email address to add to the suppression list',
|
||||
},
|
||||
reason: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The reason the address is suppressed: BOUNCE or COMPLAINT',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/put-suppressed-destination',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailAddress: params.emailAddress,
|
||||
reason: params.reason,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to add suppressed destination')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import type { SESSendBulkEmailParams, SESSendBulkEmailResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const sendBulkEmailTool: ToolConfig<SESSendBulkEmailParams, SESSendBulkEmailResponse> = {
|
||||
id: 'ses_send_bulk_email',
|
||||
name: 'SES Send Bulk Email',
|
||||
description: 'Send emails to multiple recipients using an SES template with per-recipient data',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
fromAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Verified sender email address',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the SES email template to use',
|
||||
},
|
||||
destinations: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'JSON array of destination objects with toAddresses (string[]) and optional templateData (JSON string); falls back to defaultTemplateData when omitted',
|
||||
},
|
||||
defaultTemplateData: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Default JSON template data used when a destination does not specify its own',
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'SES configuration set name for tracking',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/send-bulk-email',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
fromAddress: params.fromAddress,
|
||||
templateName: params.templateName,
|
||||
destinations: params.destinations,
|
||||
defaultTemplateData: params.defaultTemplateData,
|
||||
configurationSetName: params.configurationSetName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to send bulk email')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
results: data.results ?? [],
|
||||
successCount: data.successCount ?? 0,
|
||||
failureCount: data.failureCount ?? 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
results: {
|
||||
type: 'array',
|
||||
description: 'Per-destination send results with status and messageId',
|
||||
},
|
||||
successCount: { type: 'number', description: 'Number of successfully sent emails' },
|
||||
failureCount: { type: 'number', description: 'Number of failed email sends' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import type {
|
||||
SESSendCustomVerificationEmailParams,
|
||||
SESSendCustomVerificationEmailResponse,
|
||||
} from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const sendCustomVerificationEmailTool: ToolConfig<
|
||||
SESSendCustomVerificationEmailParams,
|
||||
SESSendCustomVerificationEmailResponse
|
||||
> = {
|
||||
id: 'ses_send_custom_verification_email',
|
||||
name: 'SES Send Custom Verification Email',
|
||||
description:
|
||||
'Send a branded custom verification email to an address using a custom verification email template',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
emailAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The email address to verify',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The name of the custom verification email template to use',
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Configuration set to use when sending the verification email',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/send-custom-verification-email',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
emailAddress: params.emailAddress,
|
||||
templateName: params.templateName,
|
||||
configurationSetName: params.configurationSetName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to send custom verification email')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
messageId: data.messageId ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
messageId: { type: 'string', description: 'SES message ID for the sent verification email' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import type { SESSendEmailParams, SESSendEmailResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const sendEmailTool: ToolConfig<SESSendEmailParams, SESSendEmailResponse> = {
|
||||
id: 'ses_send_email',
|
||||
name: 'SES Send Email',
|
||||
description: 'Send an email via AWS SES using simple or HTML content',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
fromAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Verified sender email address',
|
||||
},
|
||||
toAddresses: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of recipient email addresses',
|
||||
},
|
||||
subject: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Email subject line',
|
||||
},
|
||||
bodyText: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Plain text email body',
|
||||
},
|
||||
bodyHtml: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'HTML email body',
|
||||
},
|
||||
ccAddresses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of CC email addresses',
|
||||
},
|
||||
bccAddresses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of BCC email addresses',
|
||||
},
|
||||
replyToAddresses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of reply-to email addresses',
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'SES configuration set name for tracking',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/send-email',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
fromAddress: params.fromAddress,
|
||||
toAddresses: params.toAddresses,
|
||||
subject: params.subject,
|
||||
bodyText: params.bodyText,
|
||||
bodyHtml: params.bodyHtml,
|
||||
ccAddresses: params.ccAddresses,
|
||||
bccAddresses: params.bccAddresses,
|
||||
replyToAddresses: params.replyToAddresses,
|
||||
configurationSetName: params.configurationSetName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to send email')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
messageId: data.messageId ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
messageId: { type: 'string', description: 'SES message ID for the sent email' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import type { SESSendTemplatedEmailParams, SESSendTemplatedEmailResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const sendTemplatedEmailTool: ToolConfig<
|
||||
SESSendTemplatedEmailParams,
|
||||
SESSendTemplatedEmailResponse
|
||||
> = {
|
||||
id: 'ses_send_templated_email',
|
||||
name: 'SES Send Templated Email',
|
||||
description: 'Send an email using an SES email template with dynamic template data',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
fromAddress: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Verified sender email address',
|
||||
},
|
||||
toAddresses: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of recipient email addresses',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Name of the SES email template to use',
|
||||
},
|
||||
templateData: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'JSON string of key-value pairs for template variable substitution',
|
||||
},
|
||||
ccAddresses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of CC email addresses',
|
||||
},
|
||||
bccAddresses: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of BCC email addresses',
|
||||
},
|
||||
configurationSetName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'SES configuration set name for tracking',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/send-templated-email',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
fromAddress: params.fromAddress,
|
||||
toAddresses: params.toAddresses,
|
||||
templateName: params.templateName,
|
||||
templateData: params.templateData,
|
||||
ccAddresses: params.ccAddresses,
|
||||
bccAddresses: params.bccAddresses,
|
||||
configurationSetName: params.configurationSetName,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to send templated email')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
messageId: data.messageId ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
messageId: { type: 'string', description: 'SES message ID for the sent email' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
export interface SESConnectionConfig {
|
||||
region: string
|
||||
accessKeyId: string
|
||||
secretAccessKey: string
|
||||
}
|
||||
|
||||
export interface SESSendEmailParams extends SESConnectionConfig {
|
||||
fromAddress: string
|
||||
toAddresses: string
|
||||
subject: string
|
||||
bodyText?: string | null
|
||||
bodyHtml?: string | null
|
||||
ccAddresses?: string | null
|
||||
bccAddresses?: string | null
|
||||
replyToAddresses?: string | null
|
||||
configurationSetName?: string | null
|
||||
}
|
||||
|
||||
export interface SESSendTemplatedEmailParams extends SESConnectionConfig {
|
||||
fromAddress: string
|
||||
toAddresses: string
|
||||
templateName: string
|
||||
templateData: string
|
||||
ccAddresses?: string | null
|
||||
bccAddresses?: string | null
|
||||
configurationSetName?: string | null
|
||||
}
|
||||
|
||||
export interface SESSendBulkEmailParams extends SESConnectionConfig {
|
||||
fromAddress: string
|
||||
templateName: string
|
||||
destinations: string
|
||||
defaultTemplateData?: string | null
|
||||
configurationSetName?: string | null
|
||||
}
|
||||
|
||||
export interface SESListIdentitiesParams extends SESConnectionConfig {
|
||||
pageSize?: number | null
|
||||
nextToken?: string | null
|
||||
}
|
||||
|
||||
export interface SESGetAccountParams extends SESConnectionConfig {}
|
||||
|
||||
export interface SESCreateTemplateParams extends SESConnectionConfig {
|
||||
templateName: string
|
||||
subjectPart: string
|
||||
textPart?: string | null
|
||||
htmlPart?: string | null
|
||||
}
|
||||
|
||||
export interface SESGetTemplateParams extends SESConnectionConfig {
|
||||
templateName: string
|
||||
}
|
||||
|
||||
export interface SESListTemplatesParams extends SESConnectionConfig {
|
||||
pageSize?: number | null
|
||||
nextToken?: string | null
|
||||
}
|
||||
|
||||
export interface SESDeleteTemplateParams extends SESConnectionConfig {
|
||||
templateName: string
|
||||
}
|
||||
|
||||
export interface SESSendEmailResponse extends ToolResponse {
|
||||
output: {
|
||||
messageId: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESSendTemplatedEmailResponse extends ToolResponse {
|
||||
output: {
|
||||
messageId: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESSendBulkEmailResponse extends ToolResponse {
|
||||
output: {
|
||||
results: Array<{
|
||||
messageId: string | null
|
||||
status: string
|
||||
error: string | null
|
||||
}>
|
||||
successCount: number
|
||||
failureCount: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESListIdentitiesResponse extends ToolResponse {
|
||||
output: {
|
||||
identities: Array<{
|
||||
identityName: string
|
||||
identityType: string
|
||||
sendingEnabled: boolean
|
||||
verificationStatus: string
|
||||
}>
|
||||
nextToken: string | null
|
||||
count: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESGetAccountResponse extends ToolResponse {
|
||||
output: {
|
||||
sendingEnabled: boolean
|
||||
max24HourSend: number
|
||||
maxSendRate: number
|
||||
sentLast24Hours: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESCreateTemplateResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESGetTemplateResponse extends ToolResponse {
|
||||
output: {
|
||||
templateName: string
|
||||
subjectPart: string
|
||||
textPart: string | null
|
||||
htmlPart: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESListTemplatesResponse extends ToolResponse {
|
||||
output: {
|
||||
templates: Array<{
|
||||
templateName: string
|
||||
createdTimestamp: string | null
|
||||
}>
|
||||
nextToken: string | null
|
||||
count: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESDeleteTemplateResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESPutSuppressedDestinationParams extends SESConnectionConfig {
|
||||
emailAddress: string
|
||||
reason: 'BOUNCE' | 'COMPLAINT'
|
||||
}
|
||||
|
||||
export interface SESPutSuppressedDestinationResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESDeleteSuppressedDestinationParams extends SESConnectionConfig {
|
||||
emailAddress: string
|
||||
}
|
||||
|
||||
export interface SESDeleteSuppressedDestinationResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESGetSuppressedDestinationParams extends SESConnectionConfig {
|
||||
emailAddress: string
|
||||
}
|
||||
|
||||
export interface SESGetSuppressedDestinationResponse extends ToolResponse {
|
||||
output: {
|
||||
emailAddress: string
|
||||
reason: string
|
||||
lastUpdateTime: string | null
|
||||
messageId: string | null
|
||||
feedbackId: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESListSuppressedDestinationsParams extends SESConnectionConfig {
|
||||
reasons?: string | null
|
||||
startDate?: string | null
|
||||
endDate?: string | null
|
||||
pageSize?: number | null
|
||||
nextToken?: string | null
|
||||
}
|
||||
|
||||
export interface SESListSuppressedDestinationsResponse extends ToolResponse {
|
||||
output: {
|
||||
destinations: Array<{
|
||||
emailAddress: string
|
||||
reason: string
|
||||
lastUpdateTime: string | null
|
||||
}>
|
||||
nextToken: string | null
|
||||
count: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESCreateEmailIdentityParams extends SESConnectionConfig {
|
||||
emailIdentity: string
|
||||
dkimSigningAttributes?: {
|
||||
domainSigningSelector?: string
|
||||
domainSigningPrivateKey?: string
|
||||
nextSigningKeyLength?: 'RSA_1024_BIT' | 'RSA_2048_BIT'
|
||||
} | null
|
||||
tags?: Array<{ key: string; value: string }> | null
|
||||
configurationSetName?: string | null
|
||||
}
|
||||
|
||||
export interface SESCreateEmailIdentityResponse extends ToolResponse {
|
||||
output: {
|
||||
identityType: string
|
||||
verifiedForSendingStatus: boolean
|
||||
dkimAttributes: {
|
||||
signingEnabled: boolean | null
|
||||
status: string | null
|
||||
tokens: string[]
|
||||
signingAttributesOrigin: string | null
|
||||
nextSigningKeyLength: string | null
|
||||
currentSigningKeyLength: string | null
|
||||
lastKeyGenerationTimestamp: string | null
|
||||
signingHostedZone: string | null
|
||||
} | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESDeleteEmailIdentityParams extends SESConnectionConfig {
|
||||
emailIdentity: string
|
||||
}
|
||||
|
||||
export interface SESDeleteEmailIdentityResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESGetEmailIdentityParams extends SESConnectionConfig {
|
||||
emailIdentity: string
|
||||
}
|
||||
|
||||
export interface SESGetEmailIdentityResponse extends ToolResponse {
|
||||
output: {
|
||||
identityType: string
|
||||
verifiedForSendingStatus: boolean
|
||||
verificationStatus: string | null
|
||||
feedbackForwardingStatus: boolean | null
|
||||
configurationSetName: string | null
|
||||
dkimAttributes: {
|
||||
signingEnabled: boolean | null
|
||||
status: string | null
|
||||
tokens: string[]
|
||||
signingAttributesOrigin: string | null
|
||||
nextSigningKeyLength: string | null
|
||||
currentSigningKeyLength: string | null
|
||||
lastKeyGenerationTimestamp: string | null
|
||||
signingHostedZone: string | null
|
||||
} | null
|
||||
mailFromAttributes: {
|
||||
mailFromDomain: string | null
|
||||
mailFromDomainStatus: string | null
|
||||
behaviorOnMxFailure: string | null
|
||||
} | null
|
||||
policies: Record<string, string> | null
|
||||
tags: Array<{ key: string; value: string }>
|
||||
verificationInfo: {
|
||||
errorType: string | null
|
||||
lastCheckedTimestamp: string | null
|
||||
lastSuccessTimestamp: string | null
|
||||
} | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESUpdateTemplateParams extends SESConnectionConfig {
|
||||
templateName: string
|
||||
subjectPart: string
|
||||
textPart?: string | null
|
||||
htmlPart?: string | null
|
||||
}
|
||||
|
||||
export interface SESUpdateTemplateResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESCreateConfigurationSetParams extends SESConnectionConfig {
|
||||
configurationSetName: string
|
||||
customRedirectDomain?: string | null
|
||||
httpsPolicy?: 'REQUIRE' | 'REQUIRE_OPEN_ONLY' | 'OPTIONAL' | null
|
||||
tlsPolicy?: 'REQUIRE' | 'OPTIONAL' | null
|
||||
sendingPoolName?: string | null
|
||||
reputationMetricsEnabled?: boolean | null
|
||||
sendingEnabled?: boolean | null
|
||||
suppressedReasons?: string | null
|
||||
tags?: Array<{ key: string; value: string }> | null
|
||||
}
|
||||
|
||||
export interface SESCreateConfigurationSetResponse extends ToolResponse {
|
||||
output: {
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface SESSendCustomVerificationEmailParams extends SESConnectionConfig {
|
||||
emailAddress: string
|
||||
templateName: string
|
||||
configurationSetName?: string | null
|
||||
}
|
||||
|
||||
export interface SESSendCustomVerificationEmailResponse extends ToolResponse {
|
||||
output: {
|
||||
messageId: string
|
||||
}
|
||||
}
|
||||
|
||||
interface SESBaseResponse extends ToolResponse {
|
||||
output: { message: string }
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import type { SESUpdateTemplateParams, SESUpdateTemplateResponse } from '@/tools/ses/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const updateTemplateTool: ToolConfig<SESUpdateTemplateParams, SESUpdateTemplateResponse> = {
|
||||
id: 'ses_update_template',
|
||||
name: 'SES Update Template',
|
||||
description: 'Update the subject, HTML, and text content of an existing SES email template',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
region: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS region (e.g., us-east-1)',
|
||||
},
|
||||
accessKeyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS access key ID',
|
||||
},
|
||||
secretAccessKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'AWS secret access key',
|
||||
},
|
||||
templateName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The name of the template to update',
|
||||
},
|
||||
subjectPart: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The subject line of the template',
|
||||
},
|
||||
htmlPart: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The HTML body of the template',
|
||||
},
|
||||
textPart: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The plain text body of the template',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/ses/update-template',
|
||||
method: 'POST',
|
||||
headers: () => ({ 'Content-Type': 'application/json' }),
|
||||
body: (params) => ({
|
||||
region: params.region,
|
||||
accessKeyId: params.accessKeyId,
|
||||
secretAccessKey: params.secretAccessKey,
|
||||
templateName: params.templateName,
|
||||
subjectPart: params.subjectPart,
|
||||
htmlPart: params.htmlPart,
|
||||
textPart: params.textPart,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Failed to update template')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: data.message ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
message: { type: 'string', description: 'Confirmation message' },
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user