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,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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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)',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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.',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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
|
||||
@@ -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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user