-
Notifications
You must be signed in to change notification settings - Fork 57
feat: multiple credentials options #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…wUpBoss integration
…tication methods - Introduced support for Follow Up Boss API Key credentials in the CredentialsPage. - Updated FollowUpBossBubble class to handle both OAuth and API Key authentication. - Modified environment variables to include FUB API credentials. - Updated shared schemas to accommodate new credential types and mappings.
…lternative authentication methods - Added support for credential groups, allowing multiple authentication methods (e.g., OAuth and API Key) to be displayed as alternatives in the UI. - Enhanced validation logic to ensure that only one credential from a group is required for successful authentication. - Updated the CreateCredentialModal to handle allowed credential types and improve user experience when selecting credentials. - Refactored the BubbleNode component to utilize centralized credential validation and grouping. - Introduced utility functions for managing credential groups and labels in shared schemas.
Suggested PR title from PearlTitle: Body: Key Changes:
This feature significantly improves the flexibility and usability of credential management, especially for services that offer multiple ways to authenticate. 🚀 "Build in Public" Social Media ContentGoogle Doc Created: View Document Suggested X Post: Suggested LinkedIn Post: I'm excited to share a recent PR that introduces Credential Groups – a robust system designed to empower users with choice and simplify our integration ecosystem. What's the challenge? Traditionally, services might demand specific, individual credentials. But what about services like Follow Up Boss that support both OAuth and API Keys? Forcing users to provide all options creates unnecessary friction. Our Solution: Credential Groups! 💡 Technical Highlights & Achievements:
This wasn't just about adding a feature; it was about rethinking our core credential management architecture to be more flexible, scalable, and user-centric. It's a testament to building systems that adapt to real-world complexities while maintaining a clean developer experience. What we learned: Designing for flexibility from the schema level up can drastically simplify future integrations and improve overall system resilience. Centralizing validation logic is key to consistency and maintainability in complex applications. How do you approach managing diverse authentication methods in your projects? Share your insights below! #SoftwareDevelopment #FrontendDevelopment #BackendDevelopment #Architecture #SystemDesign #APIs #Authentication #DevOps #ProductDevelopment #BubbleLab #OpenSource #DeveloperExperience |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements support for multiple authentication methods for services, specifically adding API Key authentication as an alternative to OAuth for Follow Up Boss. The implementation introduces a credential grouping system that allows users to choose between alternative authentication methods rather than requiring all of them.
Key Changes:
- Added
FUB_API_KEY_CREDcredential type with support for Basic authentication - Implemented credential groups configuration to mark alternative auth methods
- Enhanced UI to display grouped credentials with a unified selector and validation logic
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
packages/bubble-shared-schemas/src/types.ts |
Added new FUB_API_KEY_CRED credential type enum |
packages/bubble-shared-schemas/src/credential-schema.ts |
Introduced CredentialGroupConfig interface, CREDENTIAL_GROUPS configuration, and validation functions for handling alternative credentials |
packages/bubble-shared-schemas/src/bubble-definition-schema.ts |
Registered FUB_API_KEY_CRED in credential configuration map |
packages/bubble-core/src/bubbles/service-bubble/followupboss.ts |
Implemented getAuthHeader() method to support both OAuth (Bearer) and API Key (Basic) authentication; added list_events and get_event operations |
packages/bubble-core/src/bubbles/service-bubble/followupboss.test.ts |
Added debug console.log statements (should be removed) |
packages/bubble-core/src/bubbles/service-bubble/gemini-2.5-flash-reliability.integration.test.ts |
Contains unrelated test changes that should be separated or reverted |
packages/bubble-core/CREATE_BUBBLE_README.md |
Added comprehensive documentation for configuring alternative auth methods with credential groups |
apps/bubblelab-api/.env.example |
Added environment variables for FUB OAuth and system configuration |
apps/bubble-studio/src/pages/CredentialsPage.tsx |
Implemented grouped credential display in the credentials page with separate cards showing credentials by type label; added allowedCredentialTypes filter for the create modal |
apps/bubble-studio/src/hooks/useRunExecution.ts |
Updated credential validation to use centralized validateCredentialSelection() function |
apps/bubble-studio/src/components/BubbleNode.tsx |
Enhanced credential selector to display grouped credentials with optgroup labels and handle selection/deselection of alternative credentials |
|
|
||
| const credentials = { | ||
| [CredentialType.GOOGLE_GEMINI_CRED]: process.env.GOOGLE_API_KEY!, | ||
| [CredentialType.OPENAI_CRED]: process.env.OPENAI_API_KEY!, |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OPENAI_CRED credential is added but never used in the test. The test uses google/gemini-2.5-flash model which only requires GOOGLE_GEMINI_CRED. This unused credential should be removed to avoid confusion.
| [CredentialType.OPENAI_CRED]: process.env.OPENAI_API_KEY!, |
| export function getAlternativeCredentialsGroup( | ||
| types: CredentialType[] | ||
| ): CredentialGroupConfig | null { | ||
| if (types.length < 2) return null; |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The getAlternativeCredentialsGroup function returns null when types.length < 2, but this might not be the desired behavior for a single credential type that belongs to a group. If a bubble requires only one type (e.g., only FUB_API_KEY_CRED), this function will return null even though it's part of a group.
This could cause UI inconsistencies where a single credential from a group is not treated as part of that group. Consider whether the function should return the group config for single credential types that belong to a group, or document why this behavior is intentional.
| if (types.length < 2) return null; | |
| if (types.length === 0) return null; | |
| if (types.length === 1) { | |
| const groupName = getCredentialGroupName(types[0]); | |
| return groupName ? CREDENTIAL_GROUPS[groupName] : null; | |
| } |
| if (credentials[CredentialType.FUB_API_KEY_CRED]) { | ||
| return credentials[CredentialType.FUB_API_KEY_CRED]; | ||
| } | ||
|
|
||
| if (credentials[CredentialType.FUB_CRED]) { | ||
| return credentials[CredentialType.FUB_CRED]; | ||
| } | ||
|
|
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The chooseCredential method prioritizes FUB_API_KEY_CRED over FUB_CRED, but getAuthHeader (which actually uses the credentials) prioritizes FUB_CRED (OAuth) over FUB_API_KEY_CRED. This inconsistency could lead to confusion about which credential type takes precedence.
Recommendation: Make the priority consistent. Since OAuth is generally more secure and the comment in getAuthHeader indicates "OAuth takes priority", update chooseCredential to match this priority order (check FUB_CRED first, then FUB_API_KEY_CRED).
| if (credentials[CredentialType.FUB_API_KEY_CRED]) { | |
| return credentials[CredentialType.FUB_API_KEY_CRED]; | |
| } | |
| if (credentials[CredentialType.FUB_CRED]) { | |
| return credentials[CredentialType.FUB_CRED]; | |
| } | |
| if (credentials[CredentialType.FUB_CRED]) { | |
| return credentials[CredentialType.FUB_CRED]; | |
| } | |
| if (credentials[CredentialType.FUB_API_KEY_CRED]) { | |
| return credentials[CredentialType.FUB_API_KEY_CRED]; | |
| } |
| model: { | ||
| model: 'google/gemini-2.5-flash' as const, | ||
| temperature: 0.3, | ||
| model: 'google/gemini-2.5-flash', |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removal of as const from the model string removes type safety. Without as const, the type is widened from a specific string literal to a general string, which could allow invalid model names. Consider keeping as const for better type safety.
| model: 'google/gemini-2.5-flash', | |
| model: 'google/gemini-2.5-flash' as const, |
| model: 'google/gemini-2.5-flash' as const, | ||
| temperature: 0.3, | ||
| model: 'google/gemini-2.5-flash', | ||
| temperature: 1, |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Changing temperature from 0.3 to 1 significantly increases randomness in AI responses. For a reliability test, higher temperature (1) introduces more variability, which may make the test less stable and harder to diagnose failures. If this change is intentional for testing different temperature settings, it should be documented. Otherwise, consider reverting to 0.3 for consistency with the test's purpose.
| temperature: 1, | |
| temperature: 0.3, |
| return; | ||
| } | ||
| if (val) { | ||
| const [credType, credIdStr] = val.split(':'); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The value parsing logic using split(':') is fragile. If a credential type name contains a colon (though unlikely), this would break. Consider using a more robust delimiter or a different encoding method (e.g., split(':', 2) to limit splits, or using JSON encoding).
| const [credType, credIdStr] = val.split(':'); | |
| const [credType, credIdStr] = val.split(':', 2); |
| const testMessage = `Here is a list of my upcoming calendar events for the next 7 day(s): [{"id":"_60q30c1g60o30e1i60o4ac1g60rj8gpl88rj2c1h84s34h9g60s30c1g60o30c1g6114acq26h1jce1l6ksk8gpg64o30c1g60o30c1g60o30c1g60o32c1g60o30c1g6p0j2dpn8l14cci46ko42e9k8d144gq18h348e1i84r4cdho692g","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=XzYwcTMwYzFnNjBvMzBlMWk2MG80YWMxZzYwcmo4Z3BsODhyajJjMWg4NHMzNGg5ZzYwczMwYzFnNjBvMzBjMWc2MTE0YWNxMjZoMWpjZTFsNmtzazhncGc2NG8zMGMxZzYwbzMwYzFnNjBvMzBjMWc2MG8zMmMxZzYwbzMwYzFnNnAwajJkcG44bDE0Y2NpNDZrbzQyZTlrOGQxNDRncTE4aDM0OGUxaTg0cjRjZGhvNjkyZyBzZWxpbmFsaUBidWJibGVsYWIuYWk","created":"2025-11-19T18:53:26.000Z","updated":"2025-11-20T17:45:00.539Z","summary":"Selina<>Ani | Catchup//Intro","description":"Hi Selina - pls use this zoom link:\n\nhttps://northwestern.zoom.us/j/95437428899\n\n\n\nTalk soon!\n\n\n\nAni\n","start":{"dateTime":"2025-11-20T14:30:00-08:00","timeZone":"America/Chicago"},"end":{"dateTime":"2025-11-20T14:40:00-08:00","timeZone":"America/Chicago"},"attendees":[{"email":"selinali@bubblelab.ai","responseStatus":"needsAction"},{"email":"aniruddh.singh@kellogg.northwestern.edu","responseStatus":"accepted","displayName":"Aniruddh Singh"}],"organizer":{"email":"aniruddh.singh@kellogg.northwestern.edu","displayName":"Aniruddh Singh"},"kind":"calendar#event","etag":"\"3527321401078622\"","creator":{"email":"selinali@bubblelab.ai","self":true},"iCalUID":"040000008200E00074C5B7101A82E008000000000BE3B4C68559DC010000000000000000100000006A177EBF2D50A94CBBCADFD82A6F682E","sequence":1,"guestsCanInviteOthers":false,"privateCopy":true,"reminders":{"useDefault":true},"eventType":"default"},{"id":"ag336flo1nnrfba6sep5le5uvc","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=YWczMzZmbG8xbm5yZmJhNnNlcDVsZTV1dmMgc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-11-12T04:15:20.000Z","updated":"2025-11-14T02:33:55.143Z","summary":"Ava x Selina","description":"Follow up on Bubble Lab and Rho :)","start":{"dateTime":"2025-11-21T11:00:00-08:00","timeZone":"America/Los_Angeles"},"end":{"dateTime":"2025-11-21T11:30:00-08:00","timeZone":"America/Los_Angeles"},"attendees":[{"email":"selinali@bubblelab.ai","responseStatus":"needsAction"},{"email":"ava.gueits@rho.co","responseStatus":"accepted"}],"organizer":{"email":"ava.gueits@rho.co"},"conferenceData":{"entryPoints":[{"entryPointType":"video","uri":"https://rho-co.zoom.us/j/83815239874?pwd=QJGa04AKjAB3wiwSugualEn3t4j6pI.1&jst=2","label":"rho-co.zoom.us/j/83815239874?pwd=QJGa04AKjAB3wiwSugualEn3t4j6pI.1&jst=2","meetingCode":"83815239874","passcode":"296305"},{"regionCode":"US","entryPointType":"phone","uri":"tel:+13017158592,,83815239874#","label":"+1 301-715-8592","passcode":"296305"},{"entryPointType":"more","uri":"https://www.google.com/url?q=https://applications.zoom.us/addon/invitation/detail?meetingUuid%3D3jUImutiTVGW%252Bep5flT%252B%252Bw%253D%253D%26signature%3D20c51af573b419f9f3d80064717488b54a2c817d01f30e8fcc6a2ef136375217%26v%3D1&sa=D&source=calendar&usg=AOvVaw3GIewkNVExALqq7OpyMe1r"}],"conferenceSolution":{"key":{"type":"addOn"},"name":"Zoom Meeting","iconUri":"https://lh3.googleusercontent.com/pw/AM-JKLUkiyTEgH-6DiQP85RGtd_BORvAuFnS9katNMgwYQBJUTiDh12qtQxMJFWYH2Dj30hNsNUrr-kzKMl7jX-Qd0FR7JmVSx-Fhruf8xTPPI-wdsMYez6WJE7tz7KmqsORKBEnBTiILtMJXuMvphqKdB9X=s128-no"},"conferenceId":"83815239874","notes":"Meeting host: ava.gueits@rho.co\n\n\n\nJoin Zoom Meeting: \n\nhttps://rho-co.zoom.us/j/83815239874?pwd=QJGa04AKjAB3wiwSugualEn3t4j6pI.1&jst=2","parameters":{"addOnParameters":{"parameters":{"scriptId":"1O_9DeEljSH2vrECr8XeFYYRxFFiowFKOivqSDz316BlBcDXrF00BXrkO","realMeetingId":"83815239874","creatorUserId":"Tp36nVAITdCLdoih9VdTmA","meetingUuid":"3jUImutiTVGW+ep5flT++w==","meetingType":"2","originalEventId":"ag336flo1nnrfba6sep5le5uvc"}}}},"kind":"calendar#event","etag":"\"3526175270287294\"","creator":{"email":"ava.gueits@rho.co"},"iCalUID":"ag336flo1nnrfba6sep5le5uvc@google.com","sequence":2,"extendedProperties":{"shared":{"meetingId":"83815239874","zmMeetingNum":"83815239874","meetingParams":"{\"topic\":\"Ava x Selina\",\"type\":2,\"start_time\":\"2025-11-21T11:00:00-08:00\",\"duration\":30,\"timezone\":\"America/Los_Angeles\",\"invitees_hash\":\"le59dCFwGDjydgujs1Qc0A==\",\"all_day\":false}"}},"reminders":{"useDefault":true},"eventType":"default"},{"id":"8bqs4cocc1aar9nd60mqni9cf0","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=OGJxczRjb2NjMWFhcjluZDYwbXFuaTljZjAgc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-10-29T05:34:50.000Z","updated":"2025-11-14T16:20:39.106Z","summary":"Selina Li and Robin Lim Fang Min","description":"Event Name\n\n30 min chat with Robin\n\n\n\nLocation: This is a Google Meet web conference.\n\nYou can join this meeting from your computer, tablet, or smartphone.\n\nhttps://calendly.com/events/c2cba2a2-6425-4343-af66-c700c403bf00/google_meet\n\n\n\nNeed to make changes to this event?\n\nCancel: https://calendly.com/cancellations/116c52e8-9da4-4c84-82d7-fbbd7319773c\n\nReschedule: https://calendly.com/reschedulings/116c52e8-9da4-4c84-82d7-fbbd7319773c\n\n\n\nPowered by Calendly.com\n","location":"Google Meet (instructions in description)","start":{"dateTime":"2025-11-21T11:30:00-08:00","timeZone":"Europe/Lisbon"},"end":{"dateTime":"2025-11-21T12:00:00-08:00","timeZone":"Europe/Lisbon"},"attendees":[{"email":"selinali@bubblelab.ai","responseStatus":"needsAction"},{"email":"robinlim.fm@gmail.com","responseStatus":"accepted"},{"email":"georgi@axy.digital","responseStatus":"needsAction"},{"email":"robin@axy.digital","responseStatus":"accepted"}],"organizer":{"email":"robinlim.fm@gmail.com"},"hangoutLink":"https://meet.google.com/oib-bpxf-zec","conferenceData":{"createRequest":{"requestId":"aea8f0d5-6f9d-4a22-9462-6ddbe2c200df","conferenceSolutionKey":{"type":"hangoutsMeet"},"status":{"statusCode":"success"}},"entryPoints":[{"entryPointType":"video","uri":"https://meet.google.com/oib-bpxf-zec","label":"meet.google.com/oib-bpxf-zec"}],"conferenceSolution":{"key":{"type":"hangoutsMeet"},"name":"Google Meet","iconUri":"https://fonts.gstatic.com/s/i/productlogos/meet_2020q4/v6/web-512dp/logo_meet_2020q4_color_2x_web_512dp.png"},"conferenceId":"oib-bpxf-zec"},"kind":"calendar#event","etag":"\"3526274478213022\"","creator":{"email":"robinlim.fm@gmail.com"},"iCalUID":"8bqs4cocc1aar9nd60mqni9cf0@google.com","sequence":1,"reminders":{"useDefault":true},"eventType":"default"},{"id":"1nq9m5hbsjsh5lseqs4vvk976d","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=MW5xOW01aGJzanNoNWxzZXFzNHZ2azk3NmQgc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-11-10T19:03:04.000Z","updated":"2025-11-10T19:03:04.665Z","summary":"Edward Lunch","start":{"date":"2025-11-22"},"end":{"date":"2025-11-23"},"organizer":{"email":"selinali@bubblelab.ai"},"kind":"calendar#event","etag":"\"3525602769330206\"","creator":{"email":"selinali@bubblelab.ai","self":true},"transparency":"transparent","iCalUID":"1nq9m5hbsjsh5lseqs4vvk976d@google.com","sequence":0,"reminders":{"useDefault":false},"eventType":"default"},{"id":"quvlgdrsl1j0bdtsfu731mjflc","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=cXV2bGdkcnNsMWowYmR0c2Z1NzMxbWpmbGMgc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-11-19T00:36:36.000Z","updated":"2025-11-19T00:36:36.740Z","start":{"date":"2025-11-22"},"end":{"date":"2025-11-23"},"organizer":{"email":"selinali@bubblelab.ai"},"kind":"calendar#event","etag":"\"3527025193480574\"","creator":{"email":"selinali@bubblelab.ai","self":true},"transparency":"transparent","iCalUID":"quvlgdrsl1j0bdtsfu731mjflc@google.com","sequence":0,"reminders":{"useDefault":false},"eventType":"default"},{"id":"_clr78baj8pp4cobhb8pk8hb19926cq20clr6arjkecn6ot9edlgg","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=X2Nscjc4YmFqOHBwNGNvYmhiOHBrOGhiMTk5MjZjcTIwY2xyNmFyamtlY242b3Q5ZWRsZ2cgc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-11-17T22:48:20.000Z","updated":"2025-11-17T22:48:21.427Z","summary":"AGI, Inc. x OpenAI x Lovable REAL Agent Challenge - Open Registration","description":"Get up-to-date information at: https://luma.com/event/evt-SFrFaqZ3DEaJDfh?pk=g-ncvy3fZEBtebVVj\n\n\n\nAddress:\n\nFrontier Tower @ Spaceship 995 Market Street, San Francisco\n\n\n\n∞ REAL Agent Challenge \n\nHosted by AGI, Inc. in collaboration with OpenAI and Lovable\n\n\n\n★ Event Highlights:\n\n💰 $15,000+ in prizes\n\n💬 Fast-track interviews with AGI, Inc.\n\n🌍 Custom billboard in SF for the top winner\n\n🔥 Fireside chats with researchers from frontier AI labs\n\n🤝 VC scout referrals to a16z speedrun and Afore Capital\n\n\n\nThe REAL Agent Challenge is the world's first 3 month sprint dedicated to building frontier autonomous web and computer-use agents. We have a live global leaderboard and huge prizes.\n\nWe will be opening the challenge with a two-day hackathon in SF and we're selecting top…\n\n\n\nHosted by AGI Inc. & 4 others","location":"Frontier Tower @ Spaceship 995 Market Street, San Francisco","start":{"dateTime":"2025-11-22T10:00:00-08:00","timeZone":"UTC"},"end":{"dateTime":"2025-11-23T20:00:00-08:00","timeZone":"UTC"},"attendees":[{"email":"selinali@bubblelab.ai","responseStatus":"accepted"}],"organizer":{"email":"calendar-invite@lu.ma","displayName":"Frontier Tower SF"},"kind":"calendar#event","etag":"\"3526839402854014\"","creator":{"email":"selinali@bubblelab.ai","self":true},"transparency":"transparent","iCalUID":"evt-SFrFaqZ3DEaJDfh@events.lu.ma","sequence":185582897,"guestsCanInviteOthers":false,"privateCopy":true,"reminders":{"useDefault":true},"attachments":[{"fileUrl":"https://mail.google.com/?view=att&th=19a940134366d7e4&attid=0.1&disp=attd&zw","title":"AGI, Inc. x OpenAI x Lovable REAL Agent Challenge - Open Registration.pkpass","iconLink":""}],"eventType":"default"},{"id":"5shclj0qej7ao7jv37apodnvgt","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=NXNoY2xqMHFlajdhbzdqdjM3YXBvZG52Z3Qgc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-11-18T18:06:12.000Z","updated":"2025-11-18T18:06:12.351Z","summary":"Thomas (NEA) lunch","start":{"date":"2025-11-24"},"end":{"date":"2025-11-25"},"organizer":{"email":"selinali@bubblelab.ai"},"kind":"calendar#event","etag":"\"3526978344702142\"","creator":{"email":"selinali@bubblelab.ai","self":true},"transparency":"transparent","iCalUID":"5shclj0qej7ao7jv37apodnvgt@google.com","sequence":0,"reminders":{"useDefault":false},"eventType":"default"},{"id":"mk13hvulp7l9uqoa66acd8dn98","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=bWsxM2h2dWxwN2w5dXFvYTY2YWNkOGRuOTggc2VsaW5hbGlAYnViYmxlbGFiLmFp","created":"2025-11-17T04:29:57.000Z","updated":"2025-11-17T04:30:01.425Z","summary":"Selina Li <> Alex Rankin - 25 minutes","description":"\n\n Meeting type: 25 minutes\n\n N/A\n\n \n\n Location:\n\n N/A\n\n \n\n\n\n Provided infos:\n\n Website: bubblelab.ai\n\n \n\n Need to make changes to this meeting ?\n\n Cancel\n\n Reschedule\n\n ","start":{"dateTime":"2025-11-24T17:00:00-08:00","timeZone":"Asia/Singapore"},"end":{"dateTime":"2025-11-24T17:25:00-08:00","timeZone":"Asia/Singapore"},"attendees":[{"email":"selinali@bubblelab.ai","responseStatus":"accepted"},{"email":"alex@january.capital","responseStatus":"accepted"}],"organizer":{"email":"alex@january.capital"},"kind":"calendar#event","etag":"\"3526707602851550\"","creator":{"email":"alex@january.capital"},"iCalUID":"mk13hvulp7l9uqoa66acd8dn98@google.com","sequence":0,"reminders":{"useDefault":true},"eventType":"default"}] | ||
| Please create a summary email for me in HTML format. | ||
| - Use a clean, professional design. | ||
| - Group events by day if the range spans multiple days. | ||
| - List events chronologically. | ||
| - Highlight the time, summary, and location for each event. | ||
| - If there are any overlapping events, flag them as potential conflicts. | ||
| - Add a brief "At a Glance" summary at the top (e.g., "You have 5 events today, starting at 9:00 AM"). | ||
| - Do not include the raw JSON in the output, only the HTML content. | ||
| `; |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes to gemini-2.5-flash-reliability.integration.test.ts appear to be unrelated to the "multiple credentials options" feature. These include:
- Updated test message content (calendar events)
- Removed
as constfrom model declaration - Temperature change from 0.3 to 1
- Added unused OPENAI_CRED credential
- Formatting changes to the test message
- Missing iteration count in console output
- Removed duplicate test case
If these changes are intentional, they should be in a separate PR. If they're accidental, they should be reverted to keep this PR focused on the credential feature.
| expect(result.data?.name).toBe('followupboss'); | ||
| expect(result.data?.alias).toBe('fub'); | ||
| expect(result.data?.usageExample).toBeDefined(); | ||
| console.log(result.data?.usageExample); |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug console.log statement should be removed before merging to production. This appears to be leftover debugging code.
| const overallExecutionTime = Date.now() - overallStartTime; | ||
| console.log( | ||
| `\n⏱️ All 20 parallel requests completed in ${overallExecutionTime}ms\n` | ||
| `\n⏱️ All parallel requests completed in ${overallExecutionTime}ms\n` |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The console output message is missing the number of iterations. It should read "All 20 parallel requests completed" or use the numIterations variable: All ${numIterations} parallel requests completed.
| `\n⏱️ All parallel requests completed in ${overallExecutionTime}ms\n` | |
| `\n⏱️ All ${numIterations} parallel requests completed in ${overallExecutionTime}ms\n` |
No description provided.