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
+104
View File
@@ -0,0 +1,104 @@
import type { CalcomCancelBookingParams, CalcomCancelBookingResponse } from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const cancelBookingTool: ToolConfig<CalcomCancelBookingParams, CalcomCancelBookingResponse> =
{
id: 'calcom_cancel_booking',
name: 'Cal.com Cancel Booking',
description: 'Cancel an existing booking',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
bookingUid: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier (UID) of the booking to cancel',
},
cancellationReason: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Reason for cancelling the booking',
},
},
request: {
url: (params: CalcomCancelBookingParams) => {
return `https://api.cal.com/v2/bookings/${encodeURIComponent(params.bookingUid)}/cancel`
},
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
body: (params: CalcomCancelBookingParams) => {
const body: Record<string, unknown> = {}
if (params.cancellationReason) {
body.cancellationReason = params.cancellationReason
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Cancelled booking details',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: BOOKING_DATA_OUTPUT_PROPERTIES.uid,
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
status: {
type: 'string',
description: 'Booking status (should be cancelled)',
},
cancellationReason: BOOKING_DATA_OUTPUT_PROPERTIES.cancellationReason,
cancelledByEmail: BOOKING_DATA_OUTPUT_PROPERTIES.cancelledByEmail,
start: BOOKING_DATA_OUTPUT_PROPERTIES.start,
end: BOOKING_DATA_OUTPUT_PROPERTIES.end,
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
},
},
},
}
+95
View File
@@ -0,0 +1,95 @@
import type { CalcomConfirmBookingParams, CalcomConfirmBookingResponse } from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const confirmBookingTool: ToolConfig<
CalcomConfirmBookingParams,
CalcomConfirmBookingResponse
> = {
id: 'calcom_confirm_booking',
name: 'Cal.com Confirm Booking',
description: 'Confirm a pending booking that requires confirmation',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
bookingUid: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier (UID) of the booking to confirm',
},
},
request: {
url: (params: CalcomConfirmBookingParams) => {
return `https://api.cal.com/v2/bookings/${encodeURIComponent(params.bookingUid)}/confirm`
},
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
body: () => {
return {}
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Confirmed booking details',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: BOOKING_DATA_OUTPUT_PROPERTIES.uid,
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
status: {
type: 'string',
description: 'Booking status (should be accepted/confirmed)',
},
start: BOOKING_DATA_OUTPUT_PROPERTIES.start,
end: BOOKING_DATA_OUTPUT_PROPERTIES.end,
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
meetingUrl: BOOKING_DATA_OUTPUT_PROPERTIES.meetingUrl,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
guests: BOOKING_DATA_OUTPUT_PROPERTIES.guests,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
icsUid: BOOKING_DATA_OUTPUT_PROPERTIES.icsUid,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
},
},
},
}
+152
View File
@@ -0,0 +1,152 @@
import type { CalcomCreateBookingParams, CalcomCreateBookingResponse } from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const createBookingTool: ToolConfig<CalcomCreateBookingParams, CalcomCreateBookingResponse> =
{
id: 'calcom_create_booking',
name: 'Cal.com Create Booking',
description: 'Create a new booking on Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
eventTypeId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the event type to book',
},
start: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Start time in UTC ISO 8601 format (e.g., 2024-01-15T09:00:00Z)',
},
attendee: {
type: 'object',
required: true,
visibility: 'hidden',
description:
'Attendee information object with name, email, timeZone, and optional phoneNumber (constructed from individual attendee fields)',
},
guests: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Array of guest email addresses',
items: {
type: 'string',
description: 'Guest email address',
},
},
lengthInMinutes: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Duration of the booking in minutes (overrides event type default)',
},
metadata: {
type: 'object',
required: false,
visibility: 'user-or-llm',
description: 'Custom metadata to attach to the booking',
},
},
request: {
url: 'https://api.cal.com/v2/bookings',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
body: (params: CalcomCreateBookingParams) => {
const body: Record<string, unknown> = {
eventTypeId: params.eventTypeId,
start: params.start,
attendee: params.attendee,
}
if (params.guests && params.guests.length > 0) {
body.guests = params.guests
}
if (params.lengthInMinutes !== undefined) {
body.lengthInMinutes = params.lengthInMinutes
}
if (params.metadata) {
body.metadata = params.metadata
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Created booking details',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: BOOKING_DATA_OUTPUT_PROPERTIES.uid,
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
status: BOOKING_DATA_OUTPUT_PROPERTIES.status,
start: BOOKING_DATA_OUTPUT_PROPERTIES.start,
end: BOOKING_DATA_OUTPUT_PROPERTIES.end,
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
meetingUrl: BOOKING_DATA_OUTPUT_PROPERTIES.meetingUrl,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
absentHost: BOOKING_DATA_OUTPUT_PROPERTIES.absentHost,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
guests: BOOKING_DATA_OUTPUT_PROPERTIES.guests,
bookingFieldsResponses: BOOKING_DATA_OUTPUT_PROPERTIES.bookingFieldsResponses,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
icsUid: BOOKING_DATA_OUTPUT_PROPERTIES.icsUid,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
},
},
},
}
+221
View File
@@ -0,0 +1,221 @@
import type {
CalcomCreateEventTypeParams,
CalcomCreateEventTypeResponse,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const createEventTypeTool: ToolConfig<
CalcomCreateEventTypeParams,
CalcomCreateEventTypeResponse
> = {
id: 'calcom_create_event_type',
name: 'Cal.com Create Event Type',
description: 'Create a new event type in Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
title: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Title of the event type',
},
slug: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique slug for the event type URL',
},
lengthInMinutes: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Duration of the event in minutes',
},
description: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Description of the event type',
},
slotInterval: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Interval between available booking slots in minutes',
},
minimumBookingNotice: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum notice required before booking in minutes',
},
beforeEventBuffer: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Buffer time before the event in minutes',
},
afterEventBuffer: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Buffer time after the event in minutes',
},
scheduleId: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'ID of the schedule to use for availability',
},
disableGuests: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to disable guests from being added to bookings',
},
},
request: {
url: () => 'https://api.cal.com/v2/event-types',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-14',
}),
body: (params: CalcomCreateEventTypeParams) => {
// Validate required fields
if (!params.title || typeof params.title !== 'string' || params.title.trim() === '') {
throw new Error('title is required and must be a non-empty string')
}
if (!params.slug || typeof params.slug !== 'string' || params.slug.trim() === '') {
throw new Error('slug is required and must be a non-empty string')
}
if (
params.lengthInMinutes === undefined ||
params.lengthInMinutes === null ||
typeof params.lengthInMinutes !== 'number' ||
Number.isNaN(params.lengthInMinutes)
) {
throw new Error('lengthInMinutes is required and must be a valid number')
}
const body: Record<string, unknown> = {
title: params.title.trim(),
slug: params.slug.trim(),
lengthInMinutes: params.lengthInMinutes,
}
// Only include optional fields if they are defined, not null, and not empty strings
if (
params.description !== undefined &&
params.description !== null &&
params.description !== ''
) {
body.description = params.description
}
if (
params.slotInterval !== undefined &&
params.slotInterval !== null &&
!Number.isNaN(params.slotInterval)
) {
body.slotInterval = params.slotInterval
}
if (
params.minimumBookingNotice !== undefined &&
params.minimumBookingNotice !== null &&
!Number.isNaN(params.minimumBookingNotice)
) {
body.minimumBookingNotice = params.minimumBookingNotice
}
if (
params.beforeEventBuffer !== undefined &&
params.beforeEventBuffer !== null &&
!Number.isNaN(params.beforeEventBuffer)
) {
body.beforeEventBuffer = params.beforeEventBuffer
}
if (
params.afterEventBuffer !== undefined &&
params.afterEventBuffer !== null &&
!Number.isNaN(params.afterEventBuffer)
) {
body.afterEventBuffer = params.afterEventBuffer
}
if (
params.scheduleId !== undefined &&
params.scheduleId !== null &&
!Number.isNaN(params.scheduleId)
) {
body.scheduleId = params.scheduleId
}
if (params.disableGuests !== undefined && params.disableGuests !== null) {
body.disableGuests = params.disableGuests
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Created event type details',
properties: {
id: { type: 'number', description: 'Event type ID' },
title: { type: 'string', description: 'Event type title' },
slug: { type: 'string', description: 'Event type slug' },
description: { type: 'string', description: 'Event type description' },
lengthInMinutes: { type: 'number', description: 'Duration in minutes' },
slotInterval: { type: 'number', description: 'Slot interval in minutes' },
minimumBookingNotice: { type: 'number', description: 'Minimum booking notice in minutes' },
beforeEventBuffer: { type: 'number', description: 'Buffer before event in minutes' },
afterEventBuffer: { type: 'number', description: 'Buffer after event in minutes' },
scheduleId: { type: 'number', description: 'Schedule ID' },
disableGuests: { type: 'boolean', description: 'Whether guests are disabled' },
createdAt: { type: 'string', description: 'ISO timestamp of creation' },
updatedAt: { type: 'string', description: 'ISO timestamp of last update' },
},
},
},
}
+132
View File
@@ -0,0 +1,132 @@
import type {
CalcomAvailability,
CalcomCreateScheduleParams,
CalcomCreateScheduleResponse,
} from '@/tools/calcom/types'
import { SCHEDULE_DATA_OUTPUT_PROPERTIES } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const createScheduleTool: ToolConfig<
CalcomCreateScheduleParams,
CalcomCreateScheduleResponse
> = {
id: 'calcom_create_schedule',
name: 'Cal.com Create Schedule',
description: 'Create a new availability schedule in Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
name: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name of the schedule',
},
timeZone: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Timezone for the schedule (e.g., America/New_York)',
},
isDefault: {
type: 'boolean',
required: true,
visibility: 'user-or-llm',
description: 'Whether this schedule should be the default',
},
availability: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Availability intervals for the schedule',
items: {
type: 'object',
description: 'Availability interval',
properties: {
days: {
type: 'array',
description:
'Days of the week (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)',
},
startTime: {
type: 'string',
description: 'Start time in HH:MM format',
},
endTime: {
type: 'string',
description: 'End time in HH:MM format',
},
},
},
},
},
request: {
url: () => 'https://api.cal.com/v2/schedules',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-11',
}),
body: (params: CalcomCreateScheduleParams) => {
const body: {
name: string
timeZone: string
isDefault: boolean
availability?: CalcomAvailability[]
} = {
name: params.name,
timeZone: params.timeZone,
isDefault: params.isDefault,
}
if (params.availability) {
body.availability = params.availability
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Created schedule data',
properties: SCHEDULE_DATA_OUTPUT_PROPERTIES,
},
},
}
+105
View File
@@ -0,0 +1,105 @@
import type { CalcomDeclineBookingParams, CalcomDeclineBookingResponse } from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const declineBookingTool: ToolConfig<
CalcomDeclineBookingParams,
CalcomDeclineBookingResponse
> = {
id: 'calcom_decline_booking',
name: 'Cal.com Decline Booking',
description: 'Decline a pending booking request',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
bookingUid: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier (UID) of the booking to decline',
},
reason: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Reason for declining the booking',
},
},
request: {
url: (params: CalcomDeclineBookingParams) => {
return `https://api.cal.com/v2/bookings/${encodeURIComponent(params.bookingUid)}/decline`
},
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
body: (params: CalcomDeclineBookingParams) => {
const body: Record<string, unknown> = {}
if (params.reason) {
body.reason = params.reason
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Declined booking details',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: BOOKING_DATA_OUTPUT_PROPERTIES.uid,
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
status: {
type: 'string',
description: 'Booking status (should be cancelled/rejected)',
},
cancellationReason: BOOKING_DATA_OUTPUT_PROPERTIES.cancellationReason,
start: BOOKING_DATA_OUTPUT_PROPERTIES.start,
end: BOOKING_DATA_OUTPUT_PROPERTIES.end,
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
},
},
},
}
@@ -0,0 +1,81 @@
import type {
CalcomDeleteEventTypeParams,
CalcomDeleteEventTypeResponse,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const deleteEventTypeTool: ToolConfig<
CalcomDeleteEventTypeParams,
CalcomDeleteEventTypeResponse
> = {
id: 'calcom_delete_event_type',
name: 'Cal.com Delete Event Type',
description: 'Delete an event type from Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
eventTypeId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Event type ID to delete',
},
},
request: {
url: (params: CalcomDeleteEventTypeParams) =>
`https://api.cal.com/v2/event-types/${params.eventTypeId}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-14',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Deleted event type details',
properties: {
id: { type: 'number', description: 'Event type ID' },
lengthInMinutes: { type: 'number', description: 'Duration in minutes' },
title: { type: 'string', description: 'Event type title' },
slug: { type: 'string', description: 'Event type slug' },
},
},
},
}
+68
View File
@@ -0,0 +1,68 @@
import type { CalcomDeleteScheduleParams, CalcomDeleteScheduleResponse } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const deleteScheduleTool: ToolConfig<
CalcomDeleteScheduleParams,
CalcomDeleteScheduleResponse
> = {
id: 'calcom_delete_schedule',
name: 'Cal.com Delete Schedule',
description: 'Delete a schedule from Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
scheduleId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the schedule to delete',
},
},
request: {
url: (params: CalcomDeleteScheduleParams) =>
`https://api.cal.com/v2/schedules/${encodeURIComponent(params.scheduleId)}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-11',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status (success or error)',
},
},
}
+97
View File
@@ -0,0 +1,97 @@
import type { CalcomGetBookingParams, CalcomGetBookingResponse } from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const getBookingTool: ToolConfig<CalcomGetBookingParams, CalcomGetBookingResponse> = {
id: 'calcom_get_booking',
name: 'Cal.com Get Booking',
description: 'Get details of a specific booking by its UID',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
bookingUid: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier (UID) of the booking',
},
},
request: {
url: (params: CalcomGetBookingParams) => {
return `https://api.cal.com/v2/bookings/${encodeURIComponent(params.bookingUid)}`
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Booking details',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: BOOKING_DATA_OUTPUT_PROPERTIES.uid,
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
description: BOOKING_DATA_OUTPUT_PROPERTIES.description,
status: BOOKING_DATA_OUTPUT_PROPERTIES.status,
start: BOOKING_DATA_OUTPUT_PROPERTIES.start,
end: BOOKING_DATA_OUTPUT_PROPERTIES.end,
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
meetingUrl: BOOKING_DATA_OUTPUT_PROPERTIES.meetingUrl,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
absentHost: BOOKING_DATA_OUTPUT_PROPERTIES.absentHost,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
guests: BOOKING_DATA_OUTPUT_PROPERTIES.guests,
bookingFieldsResponses: BOOKING_DATA_OUTPUT_PROPERTIES.bookingFieldsResponses,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
rating: BOOKING_DATA_OUTPUT_PROPERTIES.rating,
icsUid: BOOKING_DATA_OUTPUT_PROPERTIES.icsUid,
cancellationReason: BOOKING_DATA_OUTPUT_PROPERTIES.cancellationReason,
reschedulingReason: BOOKING_DATA_OUTPUT_PROPERTIES.reschedulingReason,
rescheduledFromUid: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledFromUid,
rescheduledToUid: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledToUid,
cancelledByEmail: BOOKING_DATA_OUTPUT_PROPERTIES.cancelledByEmail,
rescheduledByEmail: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledByEmail,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
updatedAt: BOOKING_DATA_OUTPUT_PROPERTIES.updatedAt,
},
},
},
}
@@ -0,0 +1,61 @@
import type {
CalcomGetDefaultScheduleParams,
CalcomGetDefaultScheduleResponse,
} from '@/tools/calcom/types'
import { SCHEDULE_DATA_OUTPUT_PROPERTIES } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const getDefaultScheduleTool: ToolConfig<
CalcomGetDefaultScheduleParams,
CalcomGetDefaultScheduleResponse
> = {
id: 'calcom_get_default_schedule',
name: 'Cal.com Get Default Schedule',
description: 'Get the default availability schedule from Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
},
request: {
url: () => 'https://api.cal.com/v2/schedules/default',
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-11',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Default schedule data',
properties: SCHEDULE_DATA_OUTPUT_PROPERTIES,
},
},
}
+75
View File
@@ -0,0 +1,75 @@
import type { CalcomGetEventTypeParams, CalcomGetEventTypeResponse } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const getEventTypeTool: ToolConfig<CalcomGetEventTypeParams, CalcomGetEventTypeResponse> = {
id: 'calcom_get_event_type',
name: 'Cal.com Get Event Type',
description: 'Get detailed information about a specific event type',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
eventTypeId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Event type ID to retrieve',
},
},
request: {
url: (params: CalcomGetEventTypeParams) =>
`https://api.cal.com/v2/event-types/${params.eventTypeId}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-14',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Event type details',
properties: {
id: { type: 'number', description: 'Event type ID' },
title: { type: 'string', description: 'Event type title' },
slug: { type: 'string', description: 'Event type slug' },
description: { type: 'string', description: 'Event type description' },
lengthInMinutes: { type: 'number', description: 'Duration in minutes' },
slotInterval: { type: 'number', description: 'Slot interval in minutes' },
minimumBookingNotice: { type: 'number', description: 'Minimum booking notice in minutes' },
beforeEventBuffer: { type: 'number', description: 'Buffer before event in minutes' },
afterEventBuffer: { type: 'number', description: 'Buffer after event in minutes' },
scheduleId: { type: 'number', description: 'Schedule ID' },
disableGuests: { type: 'boolean', description: 'Whether guests are disabled' },
createdAt: { type: 'string', description: 'ISO timestamp of creation' },
updatedAt: { type: 'string', description: 'ISO timestamp of last update' },
},
},
},
}
+62
View File
@@ -0,0 +1,62 @@
import type { CalcomGetScheduleParams, CalcomGetScheduleResponse } from '@/tools/calcom/types'
import { SCHEDULE_DATA_OUTPUT_PROPERTIES } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const getScheduleTool: ToolConfig<CalcomGetScheduleParams, CalcomGetScheduleResponse> = {
id: 'calcom_get_schedule',
name: 'Cal.com Get Schedule',
description: 'Get a specific schedule by ID from Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
scheduleId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the schedule to retrieve',
},
},
request: {
url: (params: CalcomGetScheduleParams) =>
`https://api.cal.com/v2/schedules/${encodeURIComponent(params.scheduleId)}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-11',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Schedule data',
properties: SCHEDULE_DATA_OUTPUT_PROPERTIES,
},
},
}
+173
View File
@@ -0,0 +1,173 @@
import type { ToolConfig, ToolResponse } from '@/tools/types'
export interface CalcomGetSlotsParams {
accessToken: string
start: string
end: string
eventTypeId?: number
eventTypeSlug?: string
username?: string
timeZone?: string
duration?: number
}
export interface CalcomGetSlotsResponse extends ToolResponse {
output: {
status: string
/** Slots grouped by date (YYYY-MM-DD format) */
data: Record<
string,
Array<{
/** ISO 8601 timestamp of slot start time */
start: string
/** ISO 8601 timestamp of slot end time (only when format=range) */
end?: string
/** Number of attendees already booked (for seated events) */
attendeesCount?: number
/** Booking UID (for seated events) */
bookingUid?: string
}>
>
}
}
export const getSlotsTool: ToolConfig<CalcomGetSlotsParams, CalcomGetSlotsResponse> = {
id: 'calcom_get_slots',
name: 'Cal.com Get Slots',
description: 'Get available booking slots for a Cal.com event type within a time range',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
start: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Start of time range in UTC ISO 8601 format (e.g., 2024-01-15T00:00:00Z)',
},
end: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'End of time range in UTC ISO 8601 format (e.g., 2024-01-22T00:00:00Z)',
},
eventTypeId: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Event type ID for direct lookup',
},
eventTypeSlug: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Event type slug (requires username to be set)',
},
username: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Username for personal event types (required when using eventTypeSlug)',
},
timeZone: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Timezone for returned slots (defaults to UTC)',
},
duration: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Slot length in minutes',
},
},
request: {
url: (params: CalcomGetSlotsParams) => {
const baseUrl = 'https://api.cal.com/v2/slots'
const queryParams: string[] = []
queryParams.push(`start=${encodeURIComponent(params.start)}`)
queryParams.push(`end=${encodeURIComponent(params.end)}`)
if (
params.eventTypeId !== undefined &&
params.eventTypeId !== null &&
!Number.isNaN(params.eventTypeId) &&
String(params.eventTypeId) !== ''
) {
queryParams.push(`eventTypeId=${params.eventTypeId}`)
}
if (params.eventTypeSlug) {
queryParams.push(`eventTypeSlug=${encodeURIComponent(params.eventTypeSlug)}`)
}
if (params.username) {
queryParams.push(`username=${encodeURIComponent(params.username)}`)
}
if (params.timeZone) {
queryParams.push(`timeZone=${encodeURIComponent(params.timeZone)}`)
}
if (
params.duration !== undefined &&
params.duration !== null &&
!Number.isNaN(params.duration) &&
String(params.duration) !== ''
) {
queryParams.push(`duration=${params.duration}`)
}
return `${baseUrl}?${queryParams.join('&')}`
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-09-04',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'json',
description:
'Available time slots grouped by date (YYYY-MM-DD keys). Each date maps to an array of slot objects with start time, optional end time, and seated event info.',
},
},
}
+39
View File
@@ -0,0 +1,39 @@
import { cancelBookingTool } from '@/tools/calcom/cancel_booking'
import { confirmBookingTool } from '@/tools/calcom/confirm_booking'
import { createBookingTool } from '@/tools/calcom/create_booking'
import { createEventTypeTool } from '@/tools/calcom/create_event_type'
import { createScheduleTool } from '@/tools/calcom/create_schedule'
import { declineBookingTool } from '@/tools/calcom/decline_booking'
import { deleteEventTypeTool } from '@/tools/calcom/delete_event_type'
import { deleteScheduleTool } from '@/tools/calcom/delete_schedule'
import { getBookingTool } from '@/tools/calcom/get_booking'
import { getDefaultScheduleTool } from '@/tools/calcom/get_default_schedule'
import { getEventTypeTool } from '@/tools/calcom/get_event_type'
import { getScheduleTool } from '@/tools/calcom/get_schedule'
import { getSlotsTool } from '@/tools/calcom/get_slots'
import { listBookingsTool } from '@/tools/calcom/list_bookings'
import { listEventTypesTool } from '@/tools/calcom/list_event_types'
import { listSchedulesTool } from '@/tools/calcom/list_schedules'
import { rescheduleBookingTool } from '@/tools/calcom/reschedule_booking'
import { updateEventTypeTool } from '@/tools/calcom/update_event_type'
import { updateScheduleTool } from '@/tools/calcom/update_schedule'
export const calcomCancelBookingTool = cancelBookingTool
export const calcomConfirmBookingTool = confirmBookingTool
export const calcomCreateBookingTool = createBookingTool
export const calcomCreateEventTypeTool = createEventTypeTool
export const calcomCreateScheduleTool = createScheduleTool
export const calcomDeclineBookingTool = declineBookingTool
export const calcomDeleteEventTypeTool = deleteEventTypeTool
export const calcomDeleteScheduleTool = deleteScheduleTool
export const calcomGetBookingTool = getBookingTool
export const calcomGetDefaultScheduleTool = getDefaultScheduleTool
export const calcomGetEventTypeTool = getEventTypeTool
export const calcomGetScheduleTool = getScheduleTool
export const calcomGetSlotsTool = getSlotsTool
export const calcomListBookingsTool = listBookingsTool
export const calcomListEventTypesTool = listEventTypesTool
export const calcomListSchedulesTool = listSchedulesTool
export const calcomRescheduleBookingTool = rescheduleBookingTool
export const calcomUpdateEventTypeTool = updateEventTypeTool
export const calcomUpdateScheduleTool = updateScheduleTool
+142
View File
@@ -0,0 +1,142 @@
import type { CalcomListBookingsParams, CalcomListBookingsResponse } from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const listBookingsTool: ToolConfig<CalcomListBookingsParams, CalcomListBookingsResponse> = {
id: 'calcom_list_bookings',
name: 'Cal.com List Bookings',
description: 'List all bookings with optional status filter',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Filter bookings by status: upcoming, recurring, past, cancelled, or unconfirmed',
},
take: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of bookings to return (pagination limit)',
},
skip: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of bookings to skip (pagination offset)',
},
},
request: {
url: (params: CalcomListBookingsParams) => {
const baseUrl = 'https://api.cal.com/v2/bookings'
const queryParams: string[] = []
if (params.status) {
queryParams.push(`status=${encodeURIComponent(params.status)}`)
}
if (params.take !== undefined) {
queryParams.push(`take=${params.take}`)
}
if (params.skip !== undefined) {
queryParams.push(`skip=${params.skip}`)
}
return queryParams.length > 0 ? `${baseUrl}?${queryParams.join('&')}` : baseUrl
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'array',
description: 'Array of bookings',
items: {
type: 'object',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: BOOKING_DATA_OUTPUT_PROPERTIES.uid,
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
description: BOOKING_DATA_OUTPUT_PROPERTIES.description,
status: BOOKING_DATA_OUTPUT_PROPERTIES.status,
start: BOOKING_DATA_OUTPUT_PROPERTIES.start,
end: BOOKING_DATA_OUTPUT_PROPERTIES.end,
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
meetingUrl: BOOKING_DATA_OUTPUT_PROPERTIES.meetingUrl,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
absentHost: BOOKING_DATA_OUTPUT_PROPERTIES.absentHost,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
guests: BOOKING_DATA_OUTPUT_PROPERTIES.guests,
bookingFieldsResponses: BOOKING_DATA_OUTPUT_PROPERTIES.bookingFieldsResponses,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
rating: BOOKING_DATA_OUTPUT_PROPERTIES.rating,
icsUid: BOOKING_DATA_OUTPUT_PROPERTIES.icsUid,
cancellationReason: BOOKING_DATA_OUTPUT_PROPERTIES.cancellationReason,
cancelledByEmail: BOOKING_DATA_OUTPUT_PROPERTIES.cancelledByEmail,
reschedulingReason: BOOKING_DATA_OUTPUT_PROPERTIES.reschedulingReason,
rescheduledByEmail: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledByEmail,
rescheduledFromUid: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledFromUid,
rescheduledToUid: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledToUid,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
updatedAt: BOOKING_DATA_OUTPUT_PROPERTIES.updatedAt,
},
},
},
pagination: {
type: 'object',
description: 'Pagination metadata',
properties: {
totalItems: { type: 'number', description: 'Total number of items' },
remainingItems: { type: 'number', description: 'Remaining items after current page' },
returnedItems: { type: 'number', description: 'Number of items returned in this response' },
itemsPerPage: { type: 'number', description: 'Items per page' },
currentPage: { type: 'number', description: 'Current page number' },
totalPages: { type: 'number', description: 'Total number of pages' },
hasNextPage: { type: 'boolean', description: 'Whether there is a next page' },
hasPreviousPage: { type: 'boolean', description: 'Whether there is a previous page' },
},
},
},
}
+92
View File
@@ -0,0 +1,92 @@
import type { CalcomListEventTypesParams, CalcomListEventTypesResponse } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const listEventTypesTool: ToolConfig<
CalcomListEventTypesParams,
CalcomListEventTypesResponse
> = {
id: 'calcom_list_event_types',
name: 'Cal.com List Event Types',
description: 'Retrieve a list of all event types',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
sortCreatedAt: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Sort by creation date: "asc" or "desc"',
},
},
request: {
url: (params: CalcomListEventTypesParams) => {
const url = 'https://api.cal.com/v2/event-types'
const queryParams: string[] = []
if (params.sortCreatedAt) {
queryParams.push(`sortCreatedAt=${encodeURIComponent(params.sortCreatedAt)}`)
}
return queryParams.length > 0 ? `${url}?${queryParams.join('&')}` : url
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-14',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'array',
description: 'Array of event types',
items: {
type: 'object',
properties: {
id: { type: 'number', description: 'Event type ID' },
title: { type: 'string', description: 'Event type title' },
slug: { type: 'string', description: 'Event type slug' },
description: { type: 'string', description: 'Event type description' },
lengthInMinutes: { type: 'number', description: 'Duration in minutes' },
slotInterval: { type: 'number', description: 'Slot interval in minutes' },
minimumBookingNotice: {
type: 'number',
description: 'Minimum booking notice in minutes',
},
beforeEventBuffer: { type: 'number', description: 'Buffer before event in minutes' },
afterEventBuffer: { type: 'number', description: 'Buffer after event in minutes' },
scheduleId: { type: 'number', description: 'Schedule ID' },
disableGuests: { type: 'boolean', description: 'Whether guests are disabled' },
createdAt: { type: 'string', description: 'ISO timestamp of creation' },
updatedAt: { type: 'string', description: 'ISO timestamp of last update' },
},
},
},
},
}
+59
View File
@@ -0,0 +1,59 @@
import type { CalcomListSchedulesParams, CalcomListSchedulesResponse } from '@/tools/calcom/types'
import { SCHEDULE_DATA_OUTPUT_PROPERTIES } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const listSchedulesTool: ToolConfig<CalcomListSchedulesParams, CalcomListSchedulesResponse> =
{
id: 'calcom_list_schedules',
name: 'Cal.com List Schedules',
description: 'List all availability schedules from Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
},
request: {
url: () => 'https://api.cal.com/v2/schedules',
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-11',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'array',
description: 'Array of schedule objects',
items: {
type: 'object',
properties: SCHEDULE_DATA_OUTPUT_PROPERTIES,
},
},
},
}
+127
View File
@@ -0,0 +1,127 @@
import type {
CalcomRescheduleBookingParams,
CalcomRescheduleBookingResponse,
} from '@/tools/calcom/types'
import {
ATTENDEES_OUTPUT,
BOOKING_DATA_OUTPUT_PROPERTIES,
EVENT_TYPE_OUTPUT,
HOSTS_OUTPUT,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const rescheduleBookingTool: ToolConfig<
CalcomRescheduleBookingParams,
CalcomRescheduleBookingResponse
> = {
id: 'calcom_reschedule_booking',
name: 'Cal.com Reschedule Booking',
description: 'Reschedule an existing booking to a new time',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
bookingUid: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Unique identifier (UID) of the booking to reschedule',
},
start: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'New start time in UTC ISO 8601 format (e.g., 2024-01-15T09:00:00Z)',
},
reschedulingReason: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Reason for rescheduling the booking',
},
},
request: {
url: (params: CalcomRescheduleBookingParams) => {
return `https://api.cal.com/v2/bookings/${encodeURIComponent(params.bookingUid)}/reschedule`
},
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-08-13',
}),
body: (params: CalcomRescheduleBookingParams) => {
const body: Record<string, unknown> = {
start: params.start,
}
if (params.reschedulingReason) {
body.reschedulingReason = params.reschedulingReason
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Rescheduled booking details',
properties: {
id: BOOKING_DATA_OUTPUT_PROPERTIES.id,
uid: {
type: 'string',
description: 'Unique identifier for the new booking',
},
title: BOOKING_DATA_OUTPUT_PROPERTIES.title,
status: BOOKING_DATA_OUTPUT_PROPERTIES.status,
reschedulingReason: BOOKING_DATA_OUTPUT_PROPERTIES.reschedulingReason,
rescheduledFromUid: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledFromUid,
rescheduledByEmail: BOOKING_DATA_OUTPUT_PROPERTIES.rescheduledByEmail,
start: {
type: 'string',
description: 'New start time in ISO 8601 format',
},
end: {
type: 'string',
description: 'New end time in ISO 8601 format',
},
duration: BOOKING_DATA_OUTPUT_PROPERTIES.duration,
eventTypeId: BOOKING_DATA_OUTPUT_PROPERTIES.eventTypeId,
eventType: EVENT_TYPE_OUTPUT,
meetingUrl: BOOKING_DATA_OUTPUT_PROPERTIES.meetingUrl,
location: BOOKING_DATA_OUTPUT_PROPERTIES.location,
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
guests: BOOKING_DATA_OUTPUT_PROPERTIES.guests,
metadata: BOOKING_DATA_OUTPUT_PROPERTIES.metadata,
icsUid: BOOKING_DATA_OUTPUT_PROPERTIES.icsUid,
createdAt: BOOKING_DATA_OUTPUT_PROPERTIES.createdAt,
},
},
},
}
+716
View File
@@ -0,0 +1,716 @@
import type { OutputProperty, ToolResponse } from '@/tools/types'
/**
* Shared output property definitions for Cal.com booking responses.
* These are reusable across all booking-related tools to ensure consistency.
*/
/**
* Output definition for attendee objects in booking responses
*/
export const ATTENDEE_OUTPUT_PROPERTIES = {
name: { type: 'string', description: 'Attendee name' },
email: { type: 'string', description: 'Attendee actual email address' },
displayEmail: {
type: 'string',
description: 'Email shown publicly (may differ from actual email)',
},
timeZone: { type: 'string', description: 'Attendee timezone (IANA format)' },
phoneNumber: { type: 'string', description: 'Attendee phone number' },
language: { type: 'string', description: 'Attendee language preference (ISO code)' },
absent: { type: 'boolean', description: 'Whether attendee was absent' },
} as const satisfies Record<string, OutputProperty>
/**
* Output definition for host objects in booking responses
*/
export const HOST_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Host user ID' },
name: { type: 'string', description: 'Host display name' },
email: { type: 'string', description: 'Host actual email address' },
displayEmail: {
type: 'string',
description: 'Email shown publicly (may differ from actual email)',
},
username: { type: 'string', description: 'Host Cal.com username' },
timeZone: { type: 'string', description: 'Host timezone (IANA format)' },
} as const satisfies Record<string, OutputProperty>
/**
* Output definition for event type objects in booking responses
*/
export const EVENT_TYPE_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Event type ID' },
slug: { type: 'string', description: 'Event type slug' },
} as const satisfies Record<string, OutputProperty>
/**
* Complete attendees array output definition with destructured items
*/
export const ATTENDEES_OUTPUT: OutputProperty = {
type: 'array',
description: 'List of attendees',
items: {
type: 'object',
properties: ATTENDEE_OUTPUT_PROPERTIES,
},
}
/**
* Complete hosts array output definition with destructured items
*/
export const HOSTS_OUTPUT: OutputProperty = {
type: 'array',
description: 'List of hosts',
items: {
type: 'object',
properties: HOST_OUTPUT_PROPERTIES,
},
}
/**
* Complete event type object output definition
*/
export const EVENT_TYPE_OUTPUT: OutputProperty = {
type: 'object',
description: 'Event type details',
properties: EVENT_TYPE_OUTPUT_PROPERTIES,
}
/**
* Common booking data output properties shared across all booking tools
*/
export const BOOKING_DATA_OUTPUT_PROPERTIES = {
id: {
type: 'number',
description: 'Numeric booking ID',
},
uid: {
type: 'string',
description: 'Unique identifier for the booking',
},
title: {
type: 'string',
description: 'Title of the booking',
},
description: {
type: 'string',
description: 'Description of the booking',
},
status: {
type: 'string',
description: 'Booking status (e.g., accepted, pending, cancelled)',
},
start: {
type: 'string',
description: 'Start time in ISO 8601 format',
},
end: {
type: 'string',
description: 'End time in ISO 8601 format',
},
duration: {
type: 'number',
description: 'Duration in minutes',
},
eventTypeId: {
type: 'number',
description: 'Event type ID',
},
eventType: EVENT_TYPE_OUTPUT,
meetingUrl: {
type: 'string',
description: 'URL to join the meeting',
},
location: {
type: 'string',
description: 'Location of the booking',
},
absentHost: {
type: 'boolean',
description: 'Whether the host was absent',
},
attendees: ATTENDEES_OUTPUT,
hosts: HOSTS_OUTPUT,
guests: {
type: 'array',
description: 'Guest email addresses',
items: {
type: 'string',
description: 'Guest email address',
},
},
bookingFieldsResponses: {
type: 'json',
description: 'Custom booking field responses (dynamic keys based on event type configuration)',
},
metadata: {
type: 'json',
description: 'Custom metadata attached to the booking (dynamic key-value pairs)',
},
rating: {
type: 'number',
description: 'Booking rating',
},
icsUid: {
type: 'string',
description: 'ICS calendar UID',
},
createdAt: {
type: 'string',
description: 'When the booking was created',
},
updatedAt: {
type: 'string',
description: 'When the booking was last updated',
},
cancellationReason: {
type: 'string',
description: 'Reason for cancellation if cancelled',
},
reschedulingReason: {
type: 'string',
description: 'Reason for rescheduling if rescheduled',
},
rescheduledFromUid: {
type: 'string',
description: 'Original booking UID if this booking was rescheduled',
},
rescheduledToUid: {
type: 'string',
description: 'New booking UID after reschedule',
},
cancelledByEmail: {
type: 'string',
description: 'Email of person who cancelled the booking',
},
rescheduledByEmail: {
type: 'string',
description: 'Email of person who rescheduled the booking',
},
} as const satisfies Record<string, OutputProperty>
/**
* Pagination output properties for list endpoints
*/
export const PAGINATION_OUTPUT_PROPERTIES = {
totalItems: { type: 'number', description: 'Total number of items' },
remainingItems: { type: 'number', description: 'Remaining items after current page' },
returnedItems: { type: 'number', description: 'Number of items returned in this response' },
itemsPerPage: { type: 'number', description: 'Items per page' },
currentPage: { type: 'number', description: 'Current page number' },
totalPages: { type: 'number', description: 'Total number of pages' },
hasNextPage: { type: 'boolean', description: 'Whether there is a next page' },
hasPreviousPage: { type: 'boolean', description: 'Whether there is a previous page' },
} as const satisfies Record<string, OutputProperty>
/**
* Complete pagination output definition
*/
export const PAGINATION_OUTPUT: OutputProperty = {
type: 'object',
description: 'Pagination metadata',
properties: PAGINATION_OUTPUT_PROPERTIES,
}
/**
* Output definition for availability intervals in schedule responses
*/
export const AVAILABILITY_OUTPUT_PROPERTIES = {
days: {
type: 'array',
description: 'Days of the week (Monday, Tuesday, etc.)',
items: { type: 'string', description: 'Day name' },
},
startTime: { type: 'string', description: 'Start time in HH:MM format' },
endTime: { type: 'string', description: 'End time in HH:MM format' },
} as const satisfies Record<string, OutputProperty>
/**
* Output definition for schedule override objects
*/
export const OVERRIDE_OUTPUT_PROPERTIES = {
date: { type: 'string', description: 'Date in YYYY-MM-DD format' },
startTime: { type: 'string', description: 'Start time in HH:MM format' },
endTime: { type: 'string', description: 'End time in HH:MM format' },
} as const satisfies Record<string, OutputProperty>
/**
* Complete availability array output definition
*/
export const AVAILABILITY_OUTPUT: OutputProperty = {
type: 'array',
description: 'Availability windows',
items: {
type: 'object',
properties: AVAILABILITY_OUTPUT_PROPERTIES,
},
}
/**
* Complete overrides array output definition
*/
export const OVERRIDES_OUTPUT: OutputProperty = {
type: 'array',
description: 'Date-specific availability overrides',
items: {
type: 'object',
properties: OVERRIDE_OUTPUT_PROPERTIES,
},
}
/**
* Common schedule data output properties
*/
export const SCHEDULE_DATA_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Schedule ID' },
ownerId: { type: 'number', description: 'Owner user ID' },
name: { type: 'string', description: 'Schedule name' },
timeZone: { type: 'string', description: 'Timezone (e.g., America/New_York)' },
isDefault: { type: 'boolean', description: 'Whether this is the default schedule' },
availability: AVAILABILITY_OUTPUT,
overrides: OVERRIDES_OUTPUT,
} as const satisfies Record<string, OutputProperty>
/**
* Common event type data output properties
*/
export const EVENT_TYPE_DATA_OUTPUT_PROPERTIES = {
id: { type: 'number', description: 'Event type ID' },
title: { type: 'string', description: 'Event type title' },
slug: { type: 'string', description: 'URL-friendly slug' },
description: { type: 'string', description: 'Event type description' },
lengthInMinutes: { type: 'number', description: 'Duration in minutes' },
slotInterval: { type: 'number', description: 'Minutes between available slots' },
minimumBookingNotice: { type: 'number', description: 'Minimum advance notice in minutes' },
beforeEventBuffer: { type: 'number', description: 'Buffer time before event in minutes' },
afterEventBuffer: { type: 'number', description: 'Buffer time after event in minutes' },
scheduleId: { type: 'number', description: 'Associated schedule ID' },
disableGuests: { type: 'boolean', description: 'Whether guest invites are disabled' },
locations: {
type: 'array',
description: 'Meeting location options',
items: {
type: 'object',
properties: {
type: {
type: 'string',
description: 'Location type (address, link, integration, phone, etc.)',
},
address: {
type: 'string',
description: 'Physical address (for address type)',
optional: true,
},
link: { type: 'string', description: 'Meeting URL (for link type)', optional: true },
phone: { type: 'string', description: 'Phone number (for phone type)', optional: true },
integration: {
type: 'string',
description: 'Integration name (for integration type)',
optional: true,
},
public: {
type: 'boolean',
description: 'Whether location is publicly visible',
optional: true,
},
},
},
},
bookingFields: {
type: 'array',
description: 'Custom booking form fields',
items: {
type: 'object',
properties: {
type: {
type: 'string',
description: 'Field type (name, email, phone, text, select, etc.)',
},
slug: { type: 'string', description: 'Field identifier', optional: true },
label: { type: 'string', description: 'Field label' },
required: { type: 'boolean', description: 'Whether field is required', optional: true },
placeholder: { type: 'string', description: 'Placeholder text', optional: true },
options: {
type: 'array',
description: 'Options for select/multiselect fields',
optional: true,
},
hidden: { type: 'boolean', description: 'Whether field is hidden', optional: true },
isDefault: {
type: 'boolean',
description: 'Whether this is a system default field',
optional: true,
},
},
},
},
metadata: { type: 'json', description: 'Custom metadata (dynamic key-value pairs)' },
} as const satisfies Record<string, OutputProperty>
export interface CalcomCreateEventTypeParams {
accessToken: string
title: string
slug: string
lengthInMinutes: number
description?: string
slotInterval?: number
minimumBookingNotice?: number
beforeEventBuffer?: number
afterEventBuffer?: number
scheduleId?: number
disableGuests?: boolean
}
interface CalcomEventType {
id: number
title: string
slug: string
description: string | null
lengthInMinutes: number
slotInterval: number | null
minimumBookingNotice: number
beforeEventBuffer: number
afterEventBuffer: number
scheduleId: number | null
disableGuests: boolean
createdAt: string
updatedAt: string
}
export interface CalcomCreateEventTypeResponse extends ToolResponse {
output: {
status: string
data: CalcomEventType
}
}
export interface CalcomGetEventTypeParams {
accessToken: string
eventTypeId: number
}
export interface CalcomGetEventTypeResponse extends ToolResponse {
output: {
status: string
data: CalcomEventType
}
}
export interface CalcomListEventTypesParams {
accessToken: string
sortCreatedAt?: 'asc' | 'desc'
}
export interface CalcomListEventTypesResponse extends ToolResponse {
output: {
status: string
data: CalcomEventType[]
}
}
export interface CalcomUpdateEventTypeParams {
accessToken: string
eventTypeId: number
title?: string
slug?: string
lengthInMinutes?: number
description?: string
slotInterval?: number
minimumBookingNotice?: number
beforeEventBuffer?: number
afterEventBuffer?: number
scheduleId?: number
disableGuests?: boolean
}
export interface CalcomUpdateEventTypeResponse extends ToolResponse {
output: {
status: string
data: CalcomEventType
}
}
export interface CalcomDeleteEventTypeParams {
accessToken: string
eventTypeId: number
}
export interface CalcomDeleteEventTypeResponse extends ToolResponse {
output: {
deleted: boolean
message: string
}
}
/**
* Common attendee structure for Cal.com bookings
*/
interface CalcomAttendee {
name: string
email?: string
timeZone: string
phoneNumber?: string
}
/**
* Common booking structure returned by Cal.com API
*/
interface CalcomBooking {
uid: string
title: string
description?: string
hosts: Array<{
id: number
name: string
email: string
timeZone: string
}>
status: string
cancellationReason?: string
reschedulingReason?: string
rescheduledFromUid?: string
start: string
end: string
duration: number
eventTypeId: number
eventType: {
id: number
slug: string
}
meetingUrl?: string
location?: string
absentHost: boolean
createdAt: string
updatedAt?: string
metadata?: Record<string, unknown>
rating?: number
attendees: Array<{
name: string
email: string
timeZone: string
phoneNumber?: string
language: string
absent: boolean
}>
guests?: string[]
bookingFieldsResponses?: Record<string, unknown>
}
/**
* Create booking params
*/
export interface CalcomCreateBookingParams {
accessToken: string
eventTypeId: number
start: string
attendee: CalcomAttendee
guests?: string[]
lengthInMinutes?: number
metadata?: Record<string, unknown>
}
export interface CalcomCreateBookingResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking
}
}
/**
* Get booking params
*/
export interface CalcomGetBookingParams {
accessToken: string
bookingUid: string
}
export interface CalcomGetBookingResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking
}
}
/**
* List bookings params
*/
export interface CalcomListBookingsParams {
accessToken: string
status?: 'upcoming' | 'recurring' | 'past' | 'cancelled' | 'unconfirmed'
take?: number
skip?: number
}
export interface CalcomListBookingsResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking[]
}
}
/**
* Cancel booking params
*/
export interface CalcomCancelBookingParams {
accessToken: string
bookingUid: string
cancellationReason?: string
}
export interface CalcomCancelBookingResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking
}
}
/**
* Reschedule booking params
*/
export interface CalcomRescheduleBookingParams {
accessToken: string
bookingUid: string
start: string
reschedulingReason?: string
}
export interface CalcomRescheduleBookingResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking
}
}
/**
* Confirm booking params
*/
export interface CalcomConfirmBookingParams {
accessToken: string
bookingUid: string
}
export interface CalcomConfirmBookingResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking
}
}
/**
* Decline booking params
*/
export interface CalcomDeclineBookingParams {
accessToken: string
bookingUid: string
reason?: string
}
export interface CalcomDeclineBookingResponse extends ToolResponse {
output: {
status: string
data: CalcomBooking
}
}
/**
* Availability interval for a schedule
*/
export interface CalcomAvailability {
days: ('Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 'Sunday')[]
startTime: string
endTime: string
}
/**
* Schedule object returned by Cal.com API
*/
interface CalcomSchedule {
id: number
name: string
timeZone: string
isDefault: boolean
availability: CalcomAvailability[]
}
export interface CalcomCreateScheduleParams {
accessToken: string
name: string
timeZone: string
isDefault: boolean
availability?: CalcomAvailability[]
}
export interface CalcomCreateScheduleResponse extends ToolResponse {
output: {
status: string
data: CalcomSchedule
}
}
export interface CalcomGetScheduleParams {
accessToken: string
scheduleId: string
}
export interface CalcomGetScheduleResponse extends ToolResponse {
output: {
status: string
data: CalcomSchedule
}
}
export interface CalcomListSchedulesParams {
accessToken: string
}
export interface CalcomListSchedulesResponse extends ToolResponse {
output: {
status: string
data: CalcomSchedule[]
}
}
export interface CalcomUpdateScheduleParams {
accessToken: string
scheduleId: string
name?: string
timeZone?: string
isDefault?: boolean
availability?: CalcomAvailability[]
}
export interface CalcomUpdateScheduleResponse extends ToolResponse {
output: {
status: string
data: CalcomSchedule
}
}
export interface CalcomDeleteScheduleParams {
accessToken: string
scheduleId: string
}
export interface CalcomDeleteScheduleResponse extends ToolResponse {
output: {
status: string
data: {
id: number
name: string
timeZone: string
isDefault: boolean
}
}
}
export interface CalcomGetDefaultScheduleParams {
accessToken: string
}
export interface CalcomGetDefaultScheduleResponse extends ToolResponse {
output: {
status: string
data: CalcomSchedule
}
}
+223
View File
@@ -0,0 +1,223 @@
import type {
CalcomUpdateEventTypeParams,
CalcomUpdateEventTypeResponse,
} from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const updateEventTypeTool: ToolConfig<
CalcomUpdateEventTypeParams,
CalcomUpdateEventTypeResponse
> = {
id: 'calcom_update_event_type',
name: 'Cal.com Update Event Type',
description: 'Update an existing event type in Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
eventTypeId: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Event type ID to update (e.g., 12345)',
},
title: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Title of the event type',
},
slug: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Unique slug for the event type URL',
},
lengthInMinutes: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Duration of the event in minutes',
},
description: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Description of the event type',
},
slotInterval: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Interval between available booking slots in minutes',
},
minimumBookingNotice: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Minimum notice required before booking in minutes',
},
beforeEventBuffer: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Buffer time before the event in minutes',
},
afterEventBuffer: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'Buffer time after the event in minutes',
},
scheduleId: {
type: 'number',
required: false,
visibility: 'user-only',
description: 'ID of the schedule to use for availability',
},
disableGuests: {
type: 'boolean',
required: false,
visibility: 'user-only',
description: 'Whether to disable guests from being added to bookings',
},
},
request: {
url: (params: CalcomUpdateEventTypeParams) =>
`https://api.cal.com/v2/event-types/${params.eventTypeId}`,
method: 'PATCH',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-14',
}),
body: (params: CalcomUpdateEventTypeParams) => {
const body: Record<string, unknown> = {}
if (params.title !== undefined && params.title !== null && params.title !== '') {
body.title = params.title
}
if (params.slug !== undefined && params.slug !== null && params.slug !== '') {
body.slug = params.slug
}
if (
params.description !== undefined &&
params.description !== null &&
params.description !== ''
) {
body.description = params.description
}
if (
params.lengthInMinutes !== undefined &&
params.lengthInMinutes !== null &&
!Number.isNaN(params.lengthInMinutes)
) {
body.lengthInMinutes = params.lengthInMinutes
}
if (
params.slotInterval !== undefined &&
params.slotInterval !== null &&
!Number.isNaN(params.slotInterval)
) {
body.slotInterval = params.slotInterval
}
if (
params.minimumBookingNotice !== undefined &&
params.minimumBookingNotice !== null &&
!Number.isNaN(params.minimumBookingNotice)
) {
body.minimumBookingNotice = params.minimumBookingNotice
}
if (
params.beforeEventBuffer !== undefined &&
params.beforeEventBuffer !== null &&
!Number.isNaN(params.beforeEventBuffer)
) {
body.beforeEventBuffer = params.beforeEventBuffer
}
if (
params.afterEventBuffer !== undefined &&
params.afterEventBuffer !== null &&
!Number.isNaN(params.afterEventBuffer)
) {
body.afterEventBuffer = params.afterEventBuffer
}
if (
params.scheduleId !== undefined &&
params.scheduleId !== null &&
!Number.isNaN(params.scheduleId)
) {
body.scheduleId = params.scheduleId
}
if (params.disableGuests !== undefined && params.disableGuests !== null) {
body.disableGuests = params.disableGuests
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
output: data,
error:
data.error?.message || data.message || `Request failed with status ${response.status}`,
}
}
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Updated event type details',
properties: {
id: { type: 'number', description: 'Event type ID' },
title: { type: 'string', description: 'Event type title' },
slug: { type: 'string', description: 'Event type slug' },
description: { type: 'string', description: 'Event type description' },
lengthInMinutes: { type: 'number', description: 'Duration in minutes' },
slotInterval: { type: 'number', description: 'Slot interval in minutes' },
minimumBookingNotice: { type: 'number', description: 'Minimum booking notice in minutes' },
beforeEventBuffer: { type: 'number', description: 'Buffer before event in minutes' },
afterEventBuffer: { type: 'number', description: 'Buffer after event in minutes' },
scheduleId: { type: 'number', description: 'Schedule ID' },
disableGuests: { type: 'boolean', description: 'Whether guests are disabled' },
createdAt: { type: 'string', description: 'ISO timestamp of creation' },
updatedAt: { type: 'string', description: 'ISO timestamp of last update' },
},
},
},
}
+138
View File
@@ -0,0 +1,138 @@
import type {
CalcomAvailability,
CalcomUpdateScheduleParams,
CalcomUpdateScheduleResponse,
} from '@/tools/calcom/types'
import { SCHEDULE_DATA_OUTPUT_PROPERTIES } from '@/tools/calcom/types'
import type { ToolConfig } from '@/tools/types'
export const updateScheduleTool: ToolConfig<
CalcomUpdateScheduleParams,
CalcomUpdateScheduleResponse
> = {
id: 'calcom_update_schedule',
name: 'Cal.com Update Schedule',
description: 'Update an existing schedule in Cal.com',
version: '1.0.0',
oauth: {
required: true,
provider: 'calcom',
},
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
description: 'Cal.com OAuth access token',
},
scheduleId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the schedule to update',
},
name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New name for the schedule',
},
timeZone: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New timezone for the schedule (e.g., America/New_York)',
},
isDefault: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether this schedule should be the default',
},
availability: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'New availability intervals for the schedule',
items: {
type: 'object',
description: 'Availability interval',
properties: {
days: {
type: 'array',
description:
'Days of the week (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)',
},
startTime: {
type: 'string',
description: 'Start time in HH:MM format',
},
endTime: {
type: 'string',
description: 'End time in HH:MM format',
},
},
},
},
},
request: {
url: (params: CalcomUpdateScheduleParams) =>
`https://api.cal.com/v2/schedules/${encodeURIComponent(params.scheduleId)}`,
method: 'PATCH',
headers: (params) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'cal-api-version': '2024-06-11',
}),
body: (params: CalcomUpdateScheduleParams) => {
const body: {
name?: string
timeZone?: string
isDefault?: boolean
availability?: CalcomAvailability[]
} = {}
if (params.name !== undefined) {
body.name = params.name
}
if (params.timeZone !== undefined) {
body.timeZone = params.timeZone
}
if (params.isDefault !== undefined) {
body.isDefault = params.isDefault
}
if (params.availability !== undefined) {
body.availability = params.availability
}
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
return {
success: true,
output: data,
}
},
outputs: {
status: {
type: 'string',
description: 'Response status',
},
data: {
type: 'object',
description: 'Updated schedule data',
properties: SCHEDULE_DATA_OUTPUT_PROPERTIES,
},
},
}