You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: prevent false-positive Slack auth error + add custom booking field support
Fix 1: Updated getCustomErrorMessage in all 3 handlers to return generic
error when lastStreamErrorRef is set and caught error is Slack auth error.
Fix 2a: Added responses?: Record<string, unknown> to CreateBookingInput
and CreatePublicBookingInput types.
Fix 2b: Added responses parameter to book_meeting and book_meeting_public
tool schemas, passed through to API calls.
Fix 2c: Included bookingFields in list_event_types_by_username response.
Fix 2d: Added CUSTOM BOOKING FIELDS section to system prompt instructing
agent to collect required custom field values and pass as responses.
Fix 3: Hardened postAgentStream to re-throw generic error when Slack auth
error is secondary to an agent stream failure.
Also fixed duplicate rule #6 numbering in CRITICAL RULES.
Copy file name to clipboardExpand all lines: apps/chat/lib/agent.ts
+29-3Lines changed: 29 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -160,6 +160,13 @@ DURATION VALIDATION:
160
160
"You selected a 30-minute meeting, but 10:00-10:15 is only 15 minutes. Shall I book 10:00-10:30 instead, or switch to a 15-minute event type?"
161
161
- The event type duration is canonical. Use the START of the user's range as startTime.
162
162
163
+
CUSTOM BOOKING FIELDS:
164
+
- When \`list_event_types_by_username\` returns event types with \`bookingFields\`, check for fields with \`required: true\`.
165
+
- Before calling \`book_meeting_public\` (or \`book_meeting\`), ask the user for values for ALL required custom fields.
166
+
- Pass the collected values as \`responses\` in the booking call. The key is the field's \`name\` (slug), the value is the user's answer.
167
+
Example: if bookingFields includes \`{ name: "what-are-you-working-on", type: "text", required: true }\`, ask the user and pass \`responses: { "what-are-you-working-on": "their answer" }\`.
168
+
- Non-required fields can be skipped unless the user volunteers the info.
169
+
163
170
MULTI-ATTENDEE:
164
171
- Primary attendee goes in attendeeName/attendeeEmail of book_meeting.
165
172
- Additional attendees with full details (name + timezone from [Context]): use add_booking_attendee after booking.
@@ -186,9 +193,9 @@ Do NOT automatically resume an incomplete task from earlier in the conversation.
186
193
4. If check_availability returns \`totalSlots: 0\`, read the \`noSlotsReason\` and present the \`nextAvailableSlots\` as alternatives. NEVER say "I wasn't able to check" or "I couldn't check" — the check succeeded, there are just no slots for that date.
187
194
5. If check_availability returns slots, USE them in your response. Do not discard results.
188
195
6. NEVER call \`check_availability\` for another user's event type — it requires the host's auth token. Use \`check_availability_public\` instead (pass eventTypeSlug + username).
189
-
6. Never call a tool with empty or placeholder arguments.
190
-
7. During a booking flow, sequential tool calls across steps are expected (list_event_types → check_availability → book_meeting). After completing the task, respond with text.
191
-
8. NEVER call create_event_type, update_event_type, or delete_event_type unless the user explicitly asked to create/update/delete an event type.
196
+
7. Never call a tool with empty or placeholder arguments.
197
+
8. During a booking flow, sequential tool calls across steps are expected (list_event_types → check_availability → book_meeting). After completing the task, respond with text.
198
+
9. NEVER call create_event_type, update_event_type, or delete_event_type unless the user explicitly asked to create/update/delete an event type.
192
199
193
200
## Formatting Rules
194
201
${
@@ -341,6 +348,7 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
341
348
description: et.description,
342
349
hidden: et.hidden,
343
350
bookingUrl: et.bookingUrl,
351
+
bookingFields: et.bookingFields,
344
352
})),
345
353
};
346
354
}catch(err){
@@ -579,6 +587,13 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
579
587
"Email addresses of additional attendees (email-only). Use when you have emails but not full details for extra guests."
580
588
),
581
589
notes: z.string().nullable().optional().describe("Optional notes for the booking"),
590
+
responses: z
591
+
.record(z.string(),z.unknown())
592
+
.nullable()
593
+
.optional()
594
+
.describe(
595
+
"Custom booking field responses. Keys are field slugs from the event type's bookingFields, values are the user's answers. Required when the event type has required custom fields."
596
+
),
582
597
}),
583
598
execute: async({
584
599
eventTypeId,
@@ -588,6 +603,7 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
if(!token)return{error: "Account not connected."};
@@ -604,6 +620,7 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
604
620
},
605
621
guests: guestEmails?.filter(Boolean)??undefined,
606
622
notes: notes??undefined,
623
+
responses: responses??undefined,
607
624
});
608
625
609
626
return{
@@ -657,6 +674,13 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
657
674
.nullable()
658
675
.optional()
659
676
.describe("Duration in minutes. Only needed if the event type supports multiple durations."),
677
+
responses: z
678
+
.record(z.string(),z.unknown())
679
+
.nullable()
680
+
.optional()
681
+
.describe(
682
+
"Custom booking field responses. Keys are field slugs from the event type's bookingFields, values are the user's answers. Required when the event type has required custom fields."
683
+
),
660
684
}),
661
685
execute: async({
662
686
eventTypeSlug,
@@ -668,6 +692,7 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
668
692
guests,
669
693
notes,
670
694
lengthInMinutes,
695
+
responses,
671
696
})=>{
672
697
constlinked=awaitgetLinkedUser(teamId,userId);
673
698
@@ -684,6 +709,7 @@ function createCalTools(teamId: string, userId: string, lookupPlatformUser?: Loo
0 commit comments