@promptbook/cli 0.112.0-11 → 0.112.0-12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/esm/index.es.js +1250 -2
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/book-2.0/agent-source/AgentBasicInformation.d.ts +1 -1
  4. package/esm/src/book-components/Chat/Chat/ChatToolCallModal.test.d.ts +2 -0
  5. package/esm/src/book-components/Chat/Chat/renderToolCallDetails.d.ts +4 -0
  6. package/esm/src/book-components/Chat/utils/getToolCallChipletInfo.timeout.test.d.ts +1 -0
  7. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +123 -0
  8. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.test.d.ts +1 -0
  9. package/esm/src/commitments/USE_CALENDAR/USE_CALENDAR.d.ts +42 -0
  10. package/esm/src/commitments/USE_CALENDAR/USE_CALENDAR.test.d.ts +1 -0
  11. package/esm/src/commitments/USE_CALENDAR/UseCalendarToolNames.d.ts +13 -0
  12. package/esm/src/commitments/USE_CALENDAR/UseCalendarWallet.d.ts +9 -0
  13. package/esm/src/commitments/USE_CALENDAR/calendarReference.d.ts +68 -0
  14. package/esm/src/commitments/USE_CALENDAR/callGoogleCalendarApi.d.ts +19 -0
  15. package/esm/src/commitments/USE_CALENDAR/createUseCalendarToolFunctions.d.ts +8 -0
  16. package/esm/src/commitments/USE_CALENDAR/createUseCalendarTools.d.ts +7 -0
  17. package/esm/src/commitments/USE_CALENDAR/getUseCalendarToolTitles.d.ts +7 -0
  18. package/esm/src/commitments/USE_CALENDAR/normalizeConfiguredCalendars.d.ts +19 -0
  19. package/esm/src/commitments/USE_CALENDAR/resolveUseCalendarToolRuntimeOrWalletCredentialResult.d.ts +34 -0
  20. package/esm/src/commitments/_common/toolRuntimeContext.d.ts +9 -0
  21. package/esm/src/commitments/index.d.ts +2 -1
  22. package/esm/src/executables/apps/locateVscode.d.ts +7 -0
  23. package/esm/src/executables/apps/locateVscode.test.d.ts +1 -0
  24. package/esm/src/executables/browsers/locateBrowser.d.ts +10 -0
  25. package/esm/src/executables/browsers/locateBrowser.test.d.ts +1 -0
  26. package/esm/src/executables/browsers/locateChrome.d.ts +7 -0
  27. package/esm/src/executables/browsers/locateChrome.test.d.ts +1 -0
  28. package/esm/src/executables/browsers/locateDefaultSystemBrowser.d.ts +10 -0
  29. package/esm/src/executables/browsers/locateDefaultSystemBrowser.test.d.ts +1 -0
  30. package/esm/src/executables/browsers/locateEdge.d.ts +7 -0
  31. package/esm/src/executables/browsers/locateEdge.test.d.ts +1 -0
  32. package/esm/src/executables/browsers/locateFirefox.d.ts +7 -0
  33. package/esm/src/executables/browsers/locateFirefox.test.d.ts +1 -0
  34. package/esm/src/executables/browsers/locateInternetExplorer.d.ts +7 -0
  35. package/esm/src/executables/browsers/locateInternetExplorer.test.d.ts +1 -0
  36. package/esm/src/executables/browsers/locateSafari.d.ts +7 -0
  37. package/esm/src/version.d.ts +1 -1
  38. package/package.json +1 -1
  39. package/umd/index.umd.js +1255 -6
  40. package/umd/index.umd.js.map +1 -1
  41. package/umd/src/book-2.0/agent-source/AgentBasicInformation.d.ts +1 -1
  42. package/umd/src/book-components/Chat/Chat/ChatToolCallModal.test.d.ts +2 -0
  43. package/umd/src/book-components/Chat/Chat/renderToolCallDetails.d.ts +4 -0
  44. package/umd/src/book-components/Chat/utils/getToolCallChipletInfo.timeout.test.d.ts +1 -0
  45. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +123 -0
  46. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.test.d.ts +1 -0
  47. package/umd/src/commitments/USE_CALENDAR/USE_CALENDAR.d.ts +42 -0
  48. package/umd/src/commitments/USE_CALENDAR/USE_CALENDAR.test.d.ts +1 -0
  49. package/umd/src/commitments/USE_CALENDAR/UseCalendarToolNames.d.ts +13 -0
  50. package/umd/src/commitments/USE_CALENDAR/UseCalendarWallet.d.ts +9 -0
  51. package/umd/src/commitments/USE_CALENDAR/calendarReference.d.ts +68 -0
  52. package/umd/src/commitments/USE_CALENDAR/callGoogleCalendarApi.d.ts +19 -0
  53. package/umd/src/commitments/USE_CALENDAR/createUseCalendarToolFunctions.d.ts +8 -0
  54. package/umd/src/commitments/USE_CALENDAR/createUseCalendarTools.d.ts +7 -0
  55. package/umd/src/commitments/USE_CALENDAR/getUseCalendarToolTitles.d.ts +7 -0
  56. package/umd/src/commitments/USE_CALENDAR/normalizeConfiguredCalendars.d.ts +19 -0
  57. package/umd/src/commitments/USE_CALENDAR/resolveUseCalendarToolRuntimeOrWalletCredentialResult.d.ts +34 -0
  58. package/umd/src/commitments/_common/toolRuntimeContext.d.ts +9 -0
  59. package/umd/src/commitments/index.d.ts +2 -1
  60. package/umd/src/executables/apps/locateVscode.d.ts +7 -0
  61. package/umd/src/executables/apps/locateVscode.test.d.ts +1 -0
  62. package/umd/src/executables/browsers/locateBrowser.d.ts +10 -0
  63. package/umd/src/executables/browsers/locateBrowser.test.d.ts +1 -0
  64. package/umd/src/executables/browsers/locateChrome.d.ts +7 -0
  65. package/umd/src/executables/browsers/locateChrome.test.d.ts +1 -0
  66. package/umd/src/executables/browsers/locateDefaultSystemBrowser.d.ts +10 -0
  67. package/umd/src/executables/browsers/locateDefaultSystemBrowser.test.d.ts +1 -0
  68. package/umd/src/executables/browsers/locateEdge.d.ts +7 -0
  69. package/umd/src/executables/browsers/locateEdge.test.d.ts +1 -0
  70. package/umd/src/executables/browsers/locateFirefox.d.ts +7 -0
  71. package/umd/src/executables/browsers/locateFirefox.test.d.ts +1 -0
  72. package/umd/src/executables/browsers/locateInternetExplorer.d.ts +7 -0
  73. package/umd/src/executables/browsers/locateInternetExplorer.test.d.ts +1 -0
  74. package/umd/src/executables/browsers/locateSafari.d.ts +7 -0
  75. package/umd/src/version.d.ts +1 -1
package/esm/index.es.js CHANGED
@@ -20,7 +20,6 @@ import { JSDOM } from 'jsdom';
20
20
  import { Converter } from 'showdown';
21
21
  import { tmpdir } from 'os';
22
22
  import { ConfigChecker } from 'configchecker';
23
- import { locateChrome } from 'locate-app';
24
23
  import { chromium } from 'playwright';
25
24
  import glob from 'glob-promise';
26
25
  import moment from 'moment';
@@ -61,7 +60,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
61
60
  * @generated
62
61
  * @see https://github.com/webgptorg/promptbook
63
62
  */
64
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-11';
63
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-12';
65
64
  /**
66
65
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
67
66
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -17317,6 +17316,20 @@ const runBrowserResultFormatting = {
17317
17316
  },
17318
17317
  };
17319
17318
 
17319
+ /**
17320
+ * @@@
17321
+ *
17322
+ * @private within the repository
17323
+ */
17324
+ function locateChrome() {
17325
+ return locateApp({
17326
+ appName: 'Chrome',
17327
+ linuxWhich: 'google-chrome',
17328
+ windowsSuffix: '\\Google\\Chrome\\Application\\chrome.exe',
17329
+ macOsName: 'Google Chrome',
17330
+ });
17331
+ }
17332
+
17320
17333
  /**
17321
17334
  * Creates one standard abort error for cancelled retry loops.
17322
17335
  *
@@ -23870,6 +23883,1232 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
23870
23883
  * Note: [💞] Ignore a discrepancy between file name and entity name
23871
23884
  */
23872
23885
 
23886
+ /**
23887
+ * Base Google Calendar API URL.
23888
+ *
23889
+ * @private constant of callGoogleCalendarApi
23890
+ */
23891
+ const GOOGLE_CALENDAR_API_BASE_URL = 'https://www.googleapis.com/calendar/v3';
23892
+ /**
23893
+ * Runs one Google Calendar API request and parses JSON response payload.
23894
+ *
23895
+ * @private function of UseCalendarCommitmentDefinition
23896
+ */
23897
+ async function callGoogleCalendarApi(accessToken, options) {
23898
+ const url = new URL(options.path, GOOGLE_CALENDAR_API_BASE_URL);
23899
+ if (options.query) {
23900
+ for (const [key, value] of Object.entries(options.query)) {
23901
+ if (value && value.trim()) {
23902
+ url.searchParams.set(key, value);
23903
+ }
23904
+ }
23905
+ }
23906
+ const response = await fetch(url.toString(), {
23907
+ method: options.method,
23908
+ headers: {
23909
+ Authorization: `Bearer ${accessToken}`,
23910
+ Accept: 'application/json',
23911
+ 'Content-Type': 'application/json',
23912
+ },
23913
+ body: options.body ? JSON.stringify(options.body) : undefined,
23914
+ });
23915
+ const textPayload = await response.text();
23916
+ const parsedPayload = tryParseJson$2(textPayload);
23917
+ if (options.allowNotFound && response.status === 404) {
23918
+ return null;
23919
+ }
23920
+ if (!response.ok) {
23921
+ throw new Error(spaceTrim$1(`
23922
+ Google Calendar API request failed (${response.status} ${response.statusText}):
23923
+ ${extractGoogleCalendarApiErrorMessage(parsedPayload, textPayload)}
23924
+ `));
23925
+ }
23926
+ return parsedPayload;
23927
+ }
23928
+ /**
23929
+ * Parses raw text into JSON when possible.
23930
+ *
23931
+ * @private function of callGoogleCalendarApi
23932
+ */
23933
+ function tryParseJson$2(rawText) {
23934
+ if (!rawText.trim()) {
23935
+ return {};
23936
+ }
23937
+ try {
23938
+ return JSON.parse(rawText);
23939
+ }
23940
+ catch (_a) {
23941
+ return rawText;
23942
+ }
23943
+ }
23944
+ /**
23945
+ * Extracts a user-friendly Google Calendar API error message.
23946
+ *
23947
+ * @private function of callGoogleCalendarApi
23948
+ */
23949
+ function extractGoogleCalendarApiErrorMessage(parsedPayload, fallbackText) {
23950
+ if (parsedPayload && typeof parsedPayload === 'object') {
23951
+ const payload = parsedPayload;
23952
+ const errorPayload = payload.error;
23953
+ if (errorPayload && typeof errorPayload === 'object') {
23954
+ const normalizedErrorPayload = errorPayload;
23955
+ const message = typeof normalizedErrorPayload.message === 'string' ? normalizedErrorPayload.message : '';
23956
+ const errors = Array.isArray(normalizedErrorPayload.errors) ? normalizedErrorPayload.errors : [];
23957
+ const flattenedErrors = errors
23958
+ .map((errorEntry) => {
23959
+ if (!errorEntry || typeof errorEntry !== 'object') {
23960
+ return '';
23961
+ }
23962
+ const normalizedErrorEntry = errorEntry;
23963
+ const detailMessage = typeof normalizedErrorEntry.message === 'string' ? normalizedErrorEntry.message : '';
23964
+ const reason = typeof normalizedErrorEntry.reason === 'string' ? normalizedErrorEntry.reason : '';
23965
+ return [detailMessage, reason].filter(Boolean).join(' | ');
23966
+ })
23967
+ .filter(Boolean);
23968
+ if (message || flattenedErrors.length > 0) {
23969
+ return [message, ...flattenedErrors].filter(Boolean).join(' | ');
23970
+ }
23971
+ }
23972
+ }
23973
+ return fallbackText || 'Unknown Google Calendar API error';
23974
+ }
23975
+
23976
+ /**
23977
+ * Hostnames accepted for Google Calendar references.
23978
+ *
23979
+ * @private internal USE CALENDAR constant
23980
+ */
23981
+ const GOOGLE_CALENDAR_HOSTNAMES = new Set(['calendar.google.com', 'www.calendar.google.com']);
23982
+ /**
23983
+ * Default Google Calendar OAuth scopes when commitment content does not list any.
23984
+ *
23985
+ * @private internal USE CALENDAR constant
23986
+ */
23987
+ const DEFAULT_GOOGLE_CALENDAR_SCOPES = ['https://www.googleapis.com/auth/calendar'];
23988
+ /**
23989
+ * Parses one Google Calendar URL/reference into canonical details.
23990
+ *
23991
+ * Supported input forms:
23992
+ * - `https://calendar.google.com/...`
23993
+ * - `calendar.google.com/...`
23994
+ *
23995
+ * @private internal utility of USE CALENDAR commitment
23996
+ */
23997
+ function parseGoogleCalendarReference(rawReference) {
23998
+ const trimmedReference = rawReference.trim();
23999
+ if (!trimmedReference) {
24000
+ return null;
24001
+ }
24002
+ const normalizedReference = trimmedReference.startsWith('calendar.google.com/')
24003
+ ? `https://${trimmedReference}`
24004
+ : trimmedReference;
24005
+ let parsedUrl;
24006
+ try {
24007
+ parsedUrl = new URL(normalizedReference);
24008
+ }
24009
+ catch (_a) {
24010
+ return null;
24011
+ }
24012
+ if (!GOOGLE_CALENDAR_HOSTNAMES.has(parsedUrl.hostname.toLowerCase())) {
24013
+ return null;
24014
+ }
24015
+ parsedUrl.protocol = 'https:';
24016
+ parsedUrl.hash = '';
24017
+ return {
24018
+ provider: 'google',
24019
+ url: parsedUrl.toString(),
24020
+ calendarId: parseGoogleCalendarIdFromUrl(parsedUrl) || 'primary',
24021
+ scopes: [...DEFAULT_GOOGLE_CALENDAR_SCOPES],
24022
+ };
24023
+ }
24024
+ /**
24025
+ * Parses `USE CALENDAR` commitment content into calendar reference + optional instructions.
24026
+ *
24027
+ * @private internal utility of USE CALENDAR commitment
24028
+ */
24029
+ function parseUseCalendarCommitmentContent(content) {
24030
+ const trimmedContent = spaceTrim$1(content);
24031
+ if (!trimmedContent) {
24032
+ return {
24033
+ calendar: null,
24034
+ calendarUrlRaw: null,
24035
+ instructions: '',
24036
+ };
24037
+ }
24038
+ const lines = trimmedContent
24039
+ .split(/\r?\n/)
24040
+ .map((line) => line.trim())
24041
+ .filter(Boolean);
24042
+ if (lines.length === 0) {
24043
+ return {
24044
+ calendar: null,
24045
+ calendarUrlRaw: null,
24046
+ instructions: '',
24047
+ };
24048
+ }
24049
+ let calendarReferenceRaw = null;
24050
+ let calendarReference = null;
24051
+ const firstLine = lines[0] || '';
24052
+ const firstLineTokens = firstLine.split(/\s+/).filter(Boolean);
24053
+ for (const token of firstLineTokens) {
24054
+ const cleanedToken = token.replace(/[),.;:!?]+$/g, '');
24055
+ const parsedReference = parseGoogleCalendarReference(cleanedToken);
24056
+ if (!parsedReference) {
24057
+ continue;
24058
+ }
24059
+ calendarReferenceRaw = cleanedToken;
24060
+ calendarReference = parsedReference;
24061
+ break;
24062
+ }
24063
+ if (!calendarReference) {
24064
+ const firstUrl = findFirstUrlToken(trimmedContent);
24065
+ if (firstUrl) {
24066
+ calendarReferenceRaw = firstUrl;
24067
+ calendarReference = parseGoogleCalendarReference(firstUrl);
24068
+ }
24069
+ }
24070
+ const scopes = extractGoogleCalendarScopes(trimmedContent);
24071
+ if (calendarReference) {
24072
+ calendarReference = {
24073
+ ...calendarReference,
24074
+ scopes: scopes.length > 0 ? scopes : [...DEFAULT_GOOGLE_CALENDAR_SCOPES],
24075
+ tokenRef: extractTokenRef(trimmedContent),
24076
+ };
24077
+ }
24078
+ const instructionLines = [...lines];
24079
+ if (instructionLines.length > 0 && calendarReferenceRaw) {
24080
+ instructionLines[0] = removeTokenFromLine(instructionLines[0] || '', calendarReferenceRaw);
24081
+ }
24082
+ const filteredInstructionLines = instructionLines.filter((line) => !/^\s*SCOPES?\s+/i.test(line) && !line.trim().startsWith('https://www.googleapis.com/auth/'));
24083
+ return {
24084
+ calendar: calendarReference,
24085
+ calendarUrlRaw: calendarReferenceRaw,
24086
+ instructions: filteredInstructionLines.join('\n').trim(),
24087
+ };
24088
+ }
24089
+ /**
24090
+ * Attempts to resolve one concrete Google Calendar id from URL.
24091
+ *
24092
+ * @private internal utility of USE CALENDAR commitment
24093
+ */
24094
+ function parseGoogleCalendarIdFromUrl(url) {
24095
+ const rawCalendarId = url.searchParams.get('cid') || url.searchParams.get('src') || url.searchParams.get('calendarId');
24096
+ if (!rawCalendarId) {
24097
+ return null;
24098
+ }
24099
+ const decodedCalendarId = decodeURIComponent(rawCalendarId).trim();
24100
+ return decodedCalendarId || null;
24101
+ }
24102
+ /**
24103
+ * Finds the first URL-looking token in text.
24104
+ *
24105
+ * @private utility of USE CALENDAR commitment
24106
+ */
24107
+ function findFirstUrlToken(text) {
24108
+ const match = text.match(/https?:\/\/[^\s)]+/i);
24109
+ return match ? match[0] || null : null;
24110
+ }
24111
+ /**
24112
+ * Extracts Google Calendar OAuth scopes declared in commitment text.
24113
+ *
24114
+ * @private utility of USE CALENDAR commitment
24115
+ */
24116
+ function extractGoogleCalendarScopes(content) {
24117
+ const scopesFromUrls = content.match(/https:\/\/www\.googleapis\.com\/auth\/[A-Za-z0-9._/-]+/gim) || [];
24118
+ const scopesFromKeywordLines = content
24119
+ .split(/\r?\n/)
24120
+ .map((line) => line.trim())
24121
+ .filter((line) => /^\s*SCOPES?\s+/i.test(line))
24122
+ .flatMap((line) => line
24123
+ .replace(/^\s*SCOPES?\s+/i, '')
24124
+ .split(/[,\s]+/)
24125
+ .map((scope) => scope.trim())
24126
+ .filter(Boolean))
24127
+ .filter((scope) => scope.startsWith('https://www.googleapis.com/auth/'));
24128
+ const uniqueScopes = new Set();
24129
+ for (const scope of [...scopesFromUrls, ...scopesFromKeywordLines]) {
24130
+ uniqueScopes.add(scope);
24131
+ }
24132
+ return [...uniqueScopes];
24133
+ }
24134
+ /**
24135
+ * Extracts optional token reference marker from commitment text.
24136
+ *
24137
+ * @private utility of USE CALENDAR commitment
24138
+ */
24139
+ function extractTokenRef(content) {
24140
+ var _a;
24141
+ const tokenRefMatch = content.match(/@[\w.-]+/);
24142
+ const tokenRef = (_a = tokenRefMatch === null || tokenRefMatch === void 0 ? void 0 : tokenRefMatch[0]) === null || _a === void 0 ? void 0 : _a.trim();
24143
+ return tokenRef || undefined;
24144
+ }
24145
+ /**
24146
+ * Removes one specific token from one instruction line.
24147
+ *
24148
+ * @private utility of USE CALENDAR commitment
24149
+ */
24150
+ function removeTokenFromLine(line, token) {
24151
+ const tokens = line.split(/\s+/).filter(Boolean);
24152
+ const filteredTokens = tokens.filter((lineToken) => lineToken.replace(/[),.;:!?]+$/g, '') !== token);
24153
+ return filteredTokens.join(' ').trim();
24154
+ }
24155
+ /**
24156
+ * Note: [💞] Ignore a discrepancy between file name and entity name
24157
+ */
24158
+
24159
+ /**
24160
+ * Wallet metadata used by USE CALENDAR when resolving Google Calendar credentials.
24161
+ *
24162
+ * @private constant of UseCalendarCommitmentDefinition
24163
+ */
24164
+ const UseCalendarWallet = {
24165
+ service: 'google_calendar',
24166
+ key: 'use-calendar-google-token',
24167
+ };
24168
+
24169
+ /**
24170
+ * Internal error used to signal missing wallet credentials.
24171
+ *
24172
+ * @private class of resolveUseCalendarToolRuntimeOrWalletCredentialResult
24173
+ */
24174
+ class CalendarWalletCredentialRequiredError extends Error {
24175
+ constructor(options) {
24176
+ super('Google Calendar token is missing in wallet. Request it from user and store as ACCESS_TOKEN (service google_calendar, key use-calendar-google-token).');
24177
+ this.name = 'CalendarWalletCredentialRequiredError';
24178
+ this.service = UseCalendarWallet.service;
24179
+ this.key = UseCalendarWallet.key;
24180
+ this.calendarReference = options.calendarReference;
24181
+ }
24182
+ }
24183
+ /**
24184
+ * Resolves calendar runtime or returns a wallet-credential-required payload when missing.
24185
+ *
24186
+ * @private function of UseCalendarCommitmentDefinition
24187
+ */
24188
+ function resolveUseCalendarToolRuntimeOrWalletCredentialResult(args) {
24189
+ try {
24190
+ return resolveUseCalendarToolRuntime(args);
24191
+ }
24192
+ catch (error) {
24193
+ if (error instanceof CalendarWalletCredentialRequiredError) {
24194
+ return {
24195
+ walletResult: JSON.stringify(createCalendarWalletCredentialRequiredResult(error)),
24196
+ };
24197
+ }
24198
+ throw error;
24199
+ }
24200
+ }
24201
+ /**
24202
+ * Resolves runtime calendar + token for a USE CALENDAR tool call.
24203
+ *
24204
+ * @private function of resolveUseCalendarToolRuntimeOrWalletCredentialResult
24205
+ */
24206
+ function resolveUseCalendarToolRuntime(args) {
24207
+ var _a, _b;
24208
+ const runtimeContext = (readToolRuntimeContextFromToolArgs(args) ||
24209
+ {});
24210
+ const configuredCalendars = normalizeConfiguredCalendars$1((_a = runtimeContext.calendars) === null || _a === void 0 ? void 0 : _a.connections);
24211
+ const calendarArgument = normalizeOptionalText$1(args.calendarUrl);
24212
+ let calendarReference = null;
24213
+ if (calendarArgument) {
24214
+ calendarReference = parseGoogleCalendarReference(calendarArgument);
24215
+ if (!calendarReference) {
24216
+ throw new Error(`Calendar URL "${calendarArgument}" is invalid.`);
24217
+ }
24218
+ }
24219
+ else if (configuredCalendars.length === 1) {
24220
+ calendarReference = configuredCalendars[0] || null;
24221
+ }
24222
+ else if (configuredCalendars.length > 1) {
24223
+ throw new Error('Calendar is ambiguous. Provide "calendarUrl" argument with one calendar from USE CALENDAR commitments.');
24224
+ }
24225
+ else {
24226
+ throw new Error('Calendar is required. Provide "calendarUrl" argument in the tool call.');
24227
+ }
24228
+ if (!calendarReference) {
24229
+ throw new Error('Calendar is required but was not resolved.');
24230
+ }
24231
+ const accessToken = normalizeOptionalText$1((_b = runtimeContext.calendars) === null || _b === void 0 ? void 0 : _b.googleAccessToken) || '';
24232
+ if (!accessToken) {
24233
+ throw new CalendarWalletCredentialRequiredError({
24234
+ calendarReference,
24235
+ });
24236
+ }
24237
+ if (configuredCalendars.length > 0) {
24238
+ const allowedCalendarUrls = new Set(configuredCalendars.map((configuredCalendar) => configuredCalendar.url));
24239
+ if (!allowedCalendarUrls.has(calendarReference.url)) {
24240
+ throw new Error(`Calendar "${calendarReference.url}" is not configured by USE CALENDAR for this agent.`);
24241
+ }
24242
+ }
24243
+ return {
24244
+ calendarReference,
24245
+ accessToken,
24246
+ };
24247
+ }
24248
+ /**
24249
+ * Normalizes optional calendar list from runtime context.
24250
+ *
24251
+ * @private function of resolveUseCalendarToolRuntimeOrWalletCredentialResult
24252
+ */
24253
+ function normalizeConfiguredCalendars$1(rawCalendars) {
24254
+ if (!Array.isArray(rawCalendars)) {
24255
+ return [];
24256
+ }
24257
+ const calendars = [];
24258
+ const knownCalendars = new Set();
24259
+ for (const rawCalendar of rawCalendars) {
24260
+ if (!rawCalendar || typeof rawCalendar !== 'object') {
24261
+ continue;
24262
+ }
24263
+ const calendar = rawCalendar;
24264
+ const rawUrl = normalizeOptionalText$1(calendar.url);
24265
+ if (!rawUrl) {
24266
+ continue;
24267
+ }
24268
+ const parsedReference = parseGoogleCalendarReference(rawUrl);
24269
+ if (!parsedReference) {
24270
+ continue;
24271
+ }
24272
+ const key = `${parsedReference.provider}|${parsedReference.url}`;
24273
+ if (knownCalendars.has(key)) {
24274
+ continue;
24275
+ }
24276
+ knownCalendars.add(key);
24277
+ const scopes = Array.isArray(calendar.scopes)
24278
+ ? calendar.scopes
24279
+ .filter((scope) => typeof scope === 'string')
24280
+ .map((scope) => scope.trim())
24281
+ .filter(Boolean)
24282
+ : [];
24283
+ calendars.push({
24284
+ ...parsedReference,
24285
+ scopes: scopes.length > 0 ? scopes : parsedReference.scopes,
24286
+ });
24287
+ }
24288
+ return calendars;
24289
+ }
24290
+ /**
24291
+ * Converts missing-wallet errors into structured tool result payloads.
24292
+ *
24293
+ * @private function of resolveUseCalendarToolRuntimeOrWalletCredentialResult
24294
+ */
24295
+ function createCalendarWalletCredentialRequiredResult(error) {
24296
+ return {
24297
+ action: 'calendar-auth',
24298
+ status: 'wallet-credential-required',
24299
+ recordType: 'ACCESS_TOKEN',
24300
+ service: error.service,
24301
+ key: error.key,
24302
+ isUserScoped: false,
24303
+ isGlobal: false,
24304
+ provider: 'google',
24305
+ calendarUrl: error.calendarReference.url,
24306
+ scopes: error.calendarReference.scopes,
24307
+ message: error.message,
24308
+ };
24309
+ }
24310
+ /**
24311
+ * Normalizes unknown text input to trimmed non-empty string.
24312
+ *
24313
+ * @private function of resolveUseCalendarToolRuntimeOrWalletCredentialResult
24314
+ */
24315
+ function normalizeOptionalText$1(value) {
24316
+ if (typeof value !== 'string') {
24317
+ return undefined;
24318
+ }
24319
+ const trimmedValue = value.trim();
24320
+ return trimmedValue || undefined;
24321
+ }
24322
+
24323
+ /**
24324
+ * Names of tools used by the USE CALENDAR commitment.
24325
+ *
24326
+ * @private constant of UseCalendarCommitmentDefinition
24327
+ */
24328
+ const UseCalendarToolNames = {
24329
+ listEvents: 'calendar_list_events',
24330
+ getEvent: 'calendar_get_event',
24331
+ createEvent: 'calendar_create_event',
24332
+ updateEvent: 'calendar_update_event',
24333
+ deleteEvent: 'calendar_delete_event',
24334
+ inviteGuests: 'calendar_invite_guests',
24335
+ };
24336
+
24337
+ /**
24338
+ * Gets Google Calendar tool function implementations.
24339
+ *
24340
+ * @private function of UseCalendarCommitmentDefinition
24341
+ */
24342
+ function createUseCalendarToolFunctions() {
24343
+ return {
24344
+ async [UseCalendarToolNames.listEvents](args) {
24345
+ return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
24346
+ const query = {};
24347
+ if (normalizeOptionalText(args.timeMin)) {
24348
+ query.timeMin = args.timeMin.trim();
24349
+ }
24350
+ if (normalizeOptionalText(args.timeMax)) {
24351
+ query.timeMax = args.timeMax.trim();
24352
+ }
24353
+ if (normalizeOptionalText(args.query)) {
24354
+ query.q = args.query.trim();
24355
+ }
24356
+ if (typeof args.maxResults === 'number' && Number.isFinite(args.maxResults) && args.maxResults > 0) {
24357
+ query.maxResults = String(Math.floor(args.maxResults));
24358
+ }
24359
+ if (args.singleEvents !== undefined) {
24360
+ query.singleEvents = args.singleEvents ? 'true' : 'false';
24361
+ }
24362
+ if (args.orderBy === 'startTime' || args.orderBy === 'updated') {
24363
+ query.orderBy = args.orderBy;
24364
+ }
24365
+ if (normalizeOptionalText(args.timeZone)) {
24366
+ query.timeZone = args.timeZone.trim();
24367
+ }
24368
+ const payload = await callGoogleCalendarApi(accessToken, {
24369
+ method: 'GET',
24370
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events`,
24371
+ query,
24372
+ });
24373
+ const events = ((payload === null || payload === void 0 ? void 0 : payload.items) || []).map((event) => mapGoogleCalendarEvent(event));
24374
+ return JSON.stringify({
24375
+ provider: calendarReference.provider,
24376
+ calendarUrl: calendarReference.url,
24377
+ calendarId: calendarReference.calendarId,
24378
+ events,
24379
+ nextPageToken: (payload === null || payload === void 0 ? void 0 : payload.nextPageToken) || null,
24380
+ nextSyncToken: (payload === null || payload === void 0 ? void 0 : payload.nextSyncToken) || null,
24381
+ });
24382
+ });
24383
+ },
24384
+ async [UseCalendarToolNames.getEvent](args) {
24385
+ return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
24386
+ const eventId = normalizeRequiredText(args.eventId, 'eventId');
24387
+ const payload = await callGoogleCalendarApi(accessToken, {
24388
+ method: 'GET',
24389
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events/${encodeURIComponent(eventId)}`,
24390
+ });
24391
+ return JSON.stringify({
24392
+ provider: calendarReference.provider,
24393
+ calendarUrl: calendarReference.url,
24394
+ calendarId: calendarReference.calendarId,
24395
+ event: mapGoogleCalendarEvent(payload || {}),
24396
+ });
24397
+ });
24398
+ },
24399
+ async [UseCalendarToolNames.createEvent](args) {
24400
+ return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
24401
+ const requestBody = createGoogleCalendarEventPayload({
24402
+ summary: normalizeRequiredText(args.summary, 'summary'),
24403
+ description: normalizeOptionalText(args.description),
24404
+ location: normalizeOptionalText(args.location),
24405
+ start: normalizeRequiredText(args.start, 'start'),
24406
+ end: normalizeRequiredText(args.end, 'end'),
24407
+ timeZone: normalizeOptionalText(args.timeZone),
24408
+ attendees: normalizeAttendees(args.attendees),
24409
+ reminderMinutes: normalizeReminderMinutes(args.reminderMinutes),
24410
+ });
24411
+ const payload = await callGoogleCalendarApi(accessToken, {
24412
+ method: 'POST',
24413
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events`,
24414
+ query: createSendUpdatesQuery(args.sendUpdates),
24415
+ body: requestBody,
24416
+ });
24417
+ return JSON.stringify({
24418
+ provider: calendarReference.provider,
24419
+ calendarUrl: calendarReference.url,
24420
+ calendarId: calendarReference.calendarId,
24421
+ event: mapGoogleCalendarEvent(payload || {}),
24422
+ });
24423
+ });
24424
+ },
24425
+ async [UseCalendarToolNames.updateEvent](args) {
24426
+ return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
24427
+ const eventId = normalizeRequiredText(args.eventId, 'eventId');
24428
+ const requestBody = createGoogleCalendarEventPayload({
24429
+ summary: normalizeOptionalText(args.summary),
24430
+ description: normalizeOptionalText(args.description),
24431
+ location: normalizeOptionalText(args.location),
24432
+ start: normalizeOptionalText(args.start),
24433
+ end: normalizeOptionalText(args.end),
24434
+ timeZone: normalizeOptionalText(args.timeZone),
24435
+ attendees: normalizeAttendees(args.attendees),
24436
+ reminderMinutes: normalizeReminderMinutes(args.reminderMinutes),
24437
+ });
24438
+ const payload = await callGoogleCalendarApi(accessToken, {
24439
+ method: 'PATCH',
24440
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events/${encodeURIComponent(eventId)}`,
24441
+ query: createSendUpdatesQuery(args.sendUpdates),
24442
+ body: requestBody,
24443
+ });
24444
+ return JSON.stringify({
24445
+ provider: calendarReference.provider,
24446
+ calendarUrl: calendarReference.url,
24447
+ calendarId: calendarReference.calendarId,
24448
+ event: mapGoogleCalendarEvent(payload || {}),
24449
+ });
24450
+ });
24451
+ },
24452
+ async [UseCalendarToolNames.deleteEvent](args) {
24453
+ return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
24454
+ const eventId = normalizeRequiredText(args.eventId, 'eventId');
24455
+ await callGoogleCalendarApi(accessToken, {
24456
+ method: 'DELETE',
24457
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events/${encodeURIComponent(eventId)}`,
24458
+ query: createSendUpdatesQuery(args.sendUpdates),
24459
+ });
24460
+ return JSON.stringify({
24461
+ provider: calendarReference.provider,
24462
+ calendarUrl: calendarReference.url,
24463
+ calendarId: calendarReference.calendarId,
24464
+ eventId,
24465
+ status: 'deleted',
24466
+ });
24467
+ });
24468
+ },
24469
+ async [UseCalendarToolNames.inviteGuests](args) {
24470
+ return withUseCalendarRuntime(args, async ({ calendarReference, accessToken }) => {
24471
+ const eventId = normalizeRequiredText(args.eventId, 'eventId');
24472
+ const guests = normalizeAttendees(args.guests);
24473
+ if (guests.length === 0) {
24474
+ throw new Error('Tool "calendar_invite_guests" requires non-empty "guests".');
24475
+ }
24476
+ const existingEvent = await callGoogleCalendarApi(accessToken, {
24477
+ method: 'GET',
24478
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events/${encodeURIComponent(eventId)}`,
24479
+ });
24480
+ const existingAttendees = ((existingEvent === null || existingEvent === void 0 ? void 0 : existingEvent.attendees) || [])
24481
+ .map((attendee) => normalizeOptionalText(attendee.email))
24482
+ .filter((email) => Boolean(email));
24483
+ const mergedAttendees = [...new Set([...existingAttendees, ...guests])];
24484
+ const payload = await callGoogleCalendarApi(accessToken, {
24485
+ method: 'PATCH',
24486
+ path: `/calendars/${encodeGoogleCalendarId(calendarReference.calendarId)}/events/${encodeURIComponent(eventId)}`,
24487
+ query: createSendUpdatesQuery(args.sendUpdates),
24488
+ body: {
24489
+ attendees: mergedAttendees.map((email) => ({ email })),
24490
+ },
24491
+ });
24492
+ return JSON.stringify({
24493
+ provider: calendarReference.provider,
24494
+ calendarUrl: calendarReference.url,
24495
+ calendarId: calendarReference.calendarId,
24496
+ event: mapGoogleCalendarEvent(payload || {}),
24497
+ invitedGuests: guests,
24498
+ });
24499
+ });
24500
+ },
24501
+ };
24502
+ }
24503
+ /**
24504
+ * Executes one tool operation with resolved USE CALENDAR runtime.
24505
+ *
24506
+ * @private function of createUseCalendarToolFunctions
24507
+ */
24508
+ async function withUseCalendarRuntime(args, operation) {
24509
+ const runtime = resolveUseCalendarToolRuntimeOrWalletCredentialResult(args);
24510
+ if ('walletResult' in runtime) {
24511
+ return runtime.walletResult;
24512
+ }
24513
+ return operation(runtime);
24514
+ }
24515
+ /**
24516
+ * Encodes one Google calendar id for URL path usage.
24517
+ *
24518
+ * @private function of createUseCalendarToolFunctions
24519
+ */
24520
+ function encodeGoogleCalendarId(calendarId) {
24521
+ return encodeURIComponent(calendarId);
24522
+ }
24523
+ /**
24524
+ * Normalizes one required textual input.
24525
+ *
24526
+ * @private function of createUseCalendarToolFunctions
24527
+ */
24528
+ function normalizeRequiredText(value, fieldName) {
24529
+ const normalizedValue = normalizeOptionalText(value);
24530
+ if (!normalizedValue) {
24531
+ throw new Error(`Tool "${fieldName}" requires non-empty value.`);
24532
+ }
24533
+ return normalizedValue;
24534
+ }
24535
+ /**
24536
+ * Normalizes unknown text input to trimmed non-empty string.
24537
+ *
24538
+ * @private function of createUseCalendarToolFunctions
24539
+ */
24540
+ function normalizeOptionalText(value) {
24541
+ if (typeof value !== 'string') {
24542
+ return undefined;
24543
+ }
24544
+ const trimmedValue = value.trim();
24545
+ return trimmedValue || undefined;
24546
+ }
24547
+ /**
24548
+ * Normalizes optional attendee list from tool input.
24549
+ *
24550
+ * @private function of createUseCalendarToolFunctions
24551
+ */
24552
+ function normalizeAttendees(value) {
24553
+ if (!Array.isArray(value)) {
24554
+ return [];
24555
+ }
24556
+ const normalizedAttendees = value
24557
+ .filter((attendee) => typeof attendee === 'string')
24558
+ .map((attendee) => attendee.trim())
24559
+ .filter(Boolean);
24560
+ return [...new Set(normalizedAttendees)];
24561
+ }
24562
+ /**
24563
+ * Normalizes optional reminder-minute offsets from tool input.
24564
+ *
24565
+ * @private function of createUseCalendarToolFunctions
24566
+ */
24567
+ function normalizeReminderMinutes(value) {
24568
+ if (!Array.isArray(value)) {
24569
+ return [];
24570
+ }
24571
+ const reminderMinutes = value
24572
+ .filter((minute) => typeof minute === 'number' && Number.isFinite(minute))
24573
+ .map((minute) => Math.max(0, Math.floor(minute)));
24574
+ return [...new Set(reminderMinutes)];
24575
+ }
24576
+ /**
24577
+ * Builds optional `sendUpdates` query for mutating Google Calendar requests.
24578
+ *
24579
+ * @private function of createUseCalendarToolFunctions
24580
+ */
24581
+ function createSendUpdatesQuery(sendUpdates) {
24582
+ if (sendUpdates === 'all' || sendUpdates === 'externalOnly' || sendUpdates === 'none') {
24583
+ return { sendUpdates };
24584
+ }
24585
+ return {};
24586
+ }
24587
+ /**
24588
+ * Creates one Google Calendar event payload from normalized tool arguments.
24589
+ *
24590
+ * @private function of createUseCalendarToolFunctions
24591
+ */
24592
+ function createGoogleCalendarEventPayload(options) {
24593
+ const payload = {};
24594
+ if (options.summary) {
24595
+ payload.summary = options.summary;
24596
+ }
24597
+ if (options.description) {
24598
+ payload.description = options.description;
24599
+ }
24600
+ if (options.location) {
24601
+ payload.location = options.location;
24602
+ }
24603
+ if (options.start) {
24604
+ payload.start = createGoogleCalendarDateValue(options.start, options.timeZone);
24605
+ }
24606
+ if (options.end) {
24607
+ payload.end = createGoogleCalendarDateValue(options.end, options.timeZone);
24608
+ }
24609
+ if (options.attendees && options.attendees.length > 0) {
24610
+ payload.attendees = options.attendees.map((email) => ({ email }));
24611
+ }
24612
+ if (options.reminderMinutes && options.reminderMinutes.length > 0) {
24613
+ payload.reminders = {
24614
+ useDefault: false,
24615
+ overrides: options.reminderMinutes.map((minutes) => ({
24616
+ method: 'popup',
24617
+ minutes,
24618
+ })),
24619
+ };
24620
+ }
24621
+ return payload;
24622
+ }
24623
+ /**
24624
+ * Converts date/dateTime input into a Google Calendar-compatible date object.
24625
+ *
24626
+ * @private function of createUseCalendarToolFunctions
24627
+ */
24628
+ function createGoogleCalendarDateValue(value, timeZone) {
24629
+ const isDateOnly = /^\d{4}-\d{2}-\d{2}$/.test(value);
24630
+ if (isDateOnly) {
24631
+ return {
24632
+ date: value,
24633
+ };
24634
+ }
24635
+ return {
24636
+ dateTime: value,
24637
+ ...(timeZone ? { timeZone } : {}),
24638
+ };
24639
+ }
24640
+ /**
24641
+ * Maps raw Google Calendar event payload to a compact tool result object.
24642
+ *
24643
+ * @private function of createUseCalendarToolFunctions
24644
+ */
24645
+ function mapGoogleCalendarEvent(event) {
24646
+ return {
24647
+ id: event.id || null,
24648
+ summary: event.summary || null,
24649
+ description: event.description || null,
24650
+ location: event.location || null,
24651
+ status: event.status || null,
24652
+ htmlLink: event.htmlLink || null,
24653
+ start: event.start || null,
24654
+ end: event.end || null,
24655
+ organizer: event.organizer || null,
24656
+ attendees: (event.attendees || []).map((attendee) => ({
24657
+ email: attendee.email || null,
24658
+ responseStatus: attendee.responseStatus || null,
24659
+ })),
24660
+ };
24661
+ }
24662
+
24663
+ /**
24664
+ * Shared calendar URL argument description used in USE CALENDAR tool schemas.
24665
+ *
24666
+ * @private constant of createUseCalendarTools
24667
+ */
24668
+ const CALENDAR_URL_PARAMETER_DESCRIPTION = 'Google Calendar URL configured by USE CALENDAR (for example "https://calendar.google.com/...").';
24669
+ /**
24670
+ * Adds USE CALENDAR tool definitions while keeping already registered tools untouched.
24671
+ *
24672
+ * @private function of UseCalendarCommitmentDefinition
24673
+ */
24674
+ function createUseCalendarTools(existingTools) {
24675
+ const updatedTools = [...existingTools];
24676
+ const addToolIfMissing = (tool) => {
24677
+ if (!updatedTools.some((existingTool) => existingTool.name === tool.name)) {
24678
+ updatedTools.push(tool);
24679
+ }
24680
+ };
24681
+ addToolIfMissing({
24682
+ name: UseCalendarToolNames.listEvents,
24683
+ description: 'List events from a configured calendar for a time range.',
24684
+ parameters: {
24685
+ type: 'object',
24686
+ properties: {
24687
+ calendarUrl: {
24688
+ type: 'string',
24689
+ description: CALENDAR_URL_PARAMETER_DESCRIPTION,
24690
+ },
24691
+ timeMin: {
24692
+ type: 'string',
24693
+ description: 'Inclusive event start bound in ISO datetime.',
24694
+ },
24695
+ timeMax: {
24696
+ type: 'string',
24697
+ description: 'Exclusive event end bound in ISO datetime.',
24698
+ },
24699
+ query: {
24700
+ type: 'string',
24701
+ description: 'Optional free-text event search query.',
24702
+ },
24703
+ maxResults: {
24704
+ type: 'integer',
24705
+ description: 'Maximum number of events to return.',
24706
+ },
24707
+ singleEvents: {
24708
+ type: 'boolean',
24709
+ description: 'Expand recurring events into individual instances.',
24710
+ },
24711
+ orderBy: {
24712
+ type: 'string',
24713
+ description: 'Optional ordering ("startTime" or "updated").',
24714
+ },
24715
+ timeZone: {
24716
+ type: 'string',
24717
+ description: 'Optional IANA timezone for response rendering.',
24718
+ },
24719
+ },
24720
+ required: [],
24721
+ },
24722
+ });
24723
+ addToolIfMissing({
24724
+ name: UseCalendarToolNames.getEvent,
24725
+ description: 'Get one event by id from a configured calendar.',
24726
+ parameters: {
24727
+ type: 'object',
24728
+ properties: {
24729
+ calendarUrl: {
24730
+ type: 'string',
24731
+ description: CALENDAR_URL_PARAMETER_DESCRIPTION,
24732
+ },
24733
+ eventId: {
24734
+ type: 'string',
24735
+ description: 'Google Calendar event id.',
24736
+ },
24737
+ },
24738
+ required: ['eventId'],
24739
+ },
24740
+ });
24741
+ addToolIfMissing({
24742
+ name: UseCalendarToolNames.createEvent,
24743
+ description: 'Create one event in a configured calendar.',
24744
+ parameters: {
24745
+ type: 'object',
24746
+ properties: {
24747
+ calendarUrl: {
24748
+ type: 'string',
24749
+ description: CALENDAR_URL_PARAMETER_DESCRIPTION,
24750
+ },
24751
+ summary: {
24752
+ type: 'string',
24753
+ description: 'Event title/summary.',
24754
+ },
24755
+ description: {
24756
+ type: 'string',
24757
+ description: 'Optional event description.',
24758
+ },
24759
+ location: {
24760
+ type: 'string',
24761
+ description: 'Optional event location.',
24762
+ },
24763
+ start: {
24764
+ type: 'string',
24765
+ description: 'Event start as ISO datetime or date.',
24766
+ },
24767
+ end: {
24768
+ type: 'string',
24769
+ description: 'Event end as ISO datetime or date.',
24770
+ },
24771
+ timeZone: {
24772
+ type: 'string',
24773
+ description: 'Optional timezone for datetime values.',
24774
+ },
24775
+ attendees: {
24776
+ type: 'array',
24777
+ description: 'Optional guest email list.',
24778
+ },
24779
+ reminderMinutes: {
24780
+ type: 'array',
24781
+ description: 'Optional popup reminder minute offsets.',
24782
+ },
24783
+ sendUpdates: {
24784
+ type: 'string',
24785
+ description: 'Guest update policy ("all", "externalOnly", "none").',
24786
+ },
24787
+ },
24788
+ required: ['summary', 'start', 'end'],
24789
+ },
24790
+ });
24791
+ addToolIfMissing({
24792
+ name: UseCalendarToolNames.updateEvent,
24793
+ description: 'Update one existing event in a configured calendar.',
24794
+ parameters: {
24795
+ type: 'object',
24796
+ properties: {
24797
+ calendarUrl: {
24798
+ type: 'string',
24799
+ description: CALENDAR_URL_PARAMETER_DESCRIPTION,
24800
+ },
24801
+ eventId: {
24802
+ type: 'string',
24803
+ description: 'Google Calendar event id.',
24804
+ },
24805
+ summary: {
24806
+ type: 'string',
24807
+ description: 'Updated event summary.',
24808
+ },
24809
+ description: {
24810
+ type: 'string',
24811
+ description: 'Updated event description.',
24812
+ },
24813
+ location: {
24814
+ type: 'string',
24815
+ description: 'Updated event location.',
24816
+ },
24817
+ start: {
24818
+ type: 'string',
24819
+ description: 'Updated event start as ISO datetime or date.',
24820
+ },
24821
+ end: {
24822
+ type: 'string',
24823
+ description: 'Updated event end as ISO datetime or date.',
24824
+ },
24825
+ timeZone: {
24826
+ type: 'string',
24827
+ description: 'Optional timezone for datetime values.',
24828
+ },
24829
+ attendees: {
24830
+ type: 'array',
24831
+ description: 'Optional replacement guest email list.',
24832
+ },
24833
+ reminderMinutes: {
24834
+ type: 'array',
24835
+ description: 'Optional replacement popup reminder minute offsets.',
24836
+ },
24837
+ sendUpdates: {
24838
+ type: 'string',
24839
+ description: 'Guest update policy ("all", "externalOnly", "none").',
24840
+ },
24841
+ },
24842
+ required: ['eventId'],
24843
+ },
24844
+ });
24845
+ addToolIfMissing({
24846
+ name: UseCalendarToolNames.deleteEvent,
24847
+ description: 'Delete one event from a configured calendar.',
24848
+ parameters: {
24849
+ type: 'object',
24850
+ properties: {
24851
+ calendarUrl: {
24852
+ type: 'string',
24853
+ description: CALENDAR_URL_PARAMETER_DESCRIPTION,
24854
+ },
24855
+ eventId: {
24856
+ type: 'string',
24857
+ description: 'Google Calendar event id.',
24858
+ },
24859
+ sendUpdates: {
24860
+ type: 'string',
24861
+ description: 'Guest update policy ("all", "externalOnly", "none").',
24862
+ },
24863
+ },
24864
+ required: ['eventId'],
24865
+ },
24866
+ });
24867
+ addToolIfMissing({
24868
+ name: UseCalendarToolNames.inviteGuests,
24869
+ description: 'Add guests to an existing event in a configured calendar.',
24870
+ parameters: {
24871
+ type: 'object',
24872
+ properties: {
24873
+ calendarUrl: {
24874
+ type: 'string',
24875
+ description: CALENDAR_URL_PARAMETER_DESCRIPTION,
24876
+ },
24877
+ eventId: {
24878
+ type: 'string',
24879
+ description: 'Google Calendar event id.',
24880
+ },
24881
+ guests: {
24882
+ type: 'array',
24883
+ description: 'Guest email list to add to the event.',
24884
+ },
24885
+ sendUpdates: {
24886
+ type: 'string',
24887
+ description: 'Guest update policy ("all", "externalOnly", "none").',
24888
+ },
24889
+ },
24890
+ required: ['eventId', 'guests'],
24891
+ },
24892
+ });
24893
+ return updatedTools;
24894
+ }
24895
+
24896
+ /**
24897
+ * Gets human-readable tool labels for USE CALENDAR functions.
24898
+ *
24899
+ * @private function of UseCalendarCommitmentDefinition
24900
+ */
24901
+ function getUseCalendarToolTitles() {
24902
+ return {
24903
+ [UseCalendarToolNames.listEvents]: 'List calendar events',
24904
+ [UseCalendarToolNames.getEvent]: 'Get calendar event',
24905
+ [UseCalendarToolNames.createEvent]: 'Create calendar event',
24906
+ [UseCalendarToolNames.updateEvent]: 'Update calendar event',
24907
+ [UseCalendarToolNames.deleteEvent]: 'Delete calendar event',
24908
+ [UseCalendarToolNames.inviteGuests]: 'Invite calendar guests',
24909
+ };
24910
+ }
24911
+
24912
+ /**
24913
+ * Normalizes unknown metadata payload into a typed list of configured calendars.
24914
+ *
24915
+ * @private internal utility of USE CALENDAR commitment
24916
+ */
24917
+ function normalizeConfiguredCalendars(rawCalendars) {
24918
+ if (!Array.isArray(rawCalendars)) {
24919
+ return [];
24920
+ }
24921
+ const uniqueCalendars = new Set();
24922
+ const calendars = [];
24923
+ for (const rawCalendar of rawCalendars) {
24924
+ if (!rawCalendar || typeof rawCalendar !== 'object') {
24925
+ continue;
24926
+ }
24927
+ const calendar = rawCalendar;
24928
+ const provider = normalizeProvider(calendar.provider);
24929
+ const url = normalizeText(calendar.url);
24930
+ const calendarId = normalizeText(calendar.calendarId);
24931
+ if (!provider || !url || !calendarId) {
24932
+ continue;
24933
+ }
24934
+ const uniqueKey = `${provider}|${url}`;
24935
+ if (uniqueCalendars.has(uniqueKey)) {
24936
+ continue;
24937
+ }
24938
+ uniqueCalendars.add(uniqueKey);
24939
+ const scopes = Array.isArray(calendar.scopes)
24940
+ ? calendar.scopes
24941
+ .filter((scope) => typeof scope === 'string')
24942
+ .map((scope) => scope.trim())
24943
+ .filter(Boolean)
24944
+ : [];
24945
+ calendars.push({
24946
+ provider,
24947
+ url,
24948
+ calendarId,
24949
+ scopes,
24950
+ ...(normalizeText(calendar.tokenRef) ? { tokenRef: normalizeText(calendar.tokenRef) } : {}),
24951
+ });
24952
+ }
24953
+ return calendars;
24954
+ }
24955
+ /**
24956
+ * Normalizes optional provider text to one supported value.
24957
+ *
24958
+ * @private function of normalizeConfiguredCalendars
24959
+ */
24960
+ function normalizeProvider(value) {
24961
+ if (typeof value !== 'string') {
24962
+ return null;
24963
+ }
24964
+ const normalizedProvider = value.trim().toLowerCase();
24965
+ if (normalizedProvider === 'google') {
24966
+ return 'google';
24967
+ }
24968
+ return null;
24969
+ }
24970
+ /**
24971
+ * Normalizes unknown text input to trimmed non-empty string.
24972
+ *
24973
+ * @private function of normalizeConfiguredCalendars
24974
+ */
24975
+ function normalizeText(value) {
24976
+ return typeof value === 'string' ? value.trim() : '';
24977
+ }
24978
+
24979
+ /**
24980
+ * USE CALENDAR commitment definition.
24981
+ *
24982
+ * `USE CALENDAR` enables calendar tooling so the agent can read and manage events
24983
+ * in one configured Google Calendar.
24984
+ *
24985
+ * Authentication is expected through runtime context provided by the host app UI.
24986
+ * Hosts can provide manual wallet tokens or host-managed OAuth tokens.
24987
+ *
24988
+ * @private [🪔] Maybe export the commitments through some package
24989
+ */
24990
+ class UseCalendarCommitmentDefinition extends BaseCommitmentDefinition {
24991
+ constructor() {
24992
+ super('USE CALENDAR', ['CALENDAR']);
24993
+ }
24994
+ /**
24995
+ * Short one-line description of USE CALENDAR.
24996
+ */
24997
+ get description() {
24998
+ return 'Enable calendar tools for reading and managing events through Google Calendar.';
24999
+ }
25000
+ /**
25001
+ * Icon for this commitment.
25002
+ */
25003
+ get icon() {
25004
+ return '📅';
25005
+ }
25006
+ /**
25007
+ * Markdown documentation for USE CALENDAR commitment.
25008
+ */
25009
+ get documentation() {
25010
+ return spaceTrim$1(`
25011
+ # USE CALENDAR
25012
+
25013
+ Enables the agent to access and manage one Google Calendar.
25014
+
25015
+ ## Key aspects
25016
+
25017
+ - The first URL in the commitment should point to a Google Calendar URL.
25018
+ - Optional \`SCOPES\` lines can provide explicit OAuth scopes.
25019
+ - Optional extra instructions can follow calendar reference lines.
25020
+ - Runtime provides Google Calendar OAuth token (manual wallet token or host-managed OAuth token).
25021
+ - Tools support listing events, reading one event, creating events, updating events, deleting events, and inviting guests.
25022
+
25023
+ ## Examples
25024
+
25025
+ \`\`\`book
25026
+ Scheduling Assistant
25027
+
25028
+ PERSONA You coordinate meetings and schedules.
25029
+ USE CALENDAR https://calendar.google.com/calendar/u/0/r
25030
+ \`\`\`
25031
+
25032
+ \`\`\`book
25033
+ Executive Assistant
25034
+
25035
+ USE CALENDAR https://calendar.google.com/calendar/u/0/r
25036
+ SCOPES https://www.googleapis.com/auth/calendar.readonly
25037
+ RULE Ask for confirmation before deleting events.
25038
+ \`\`\`
25039
+ `);
25040
+ }
25041
+ applyToAgentModelRequirements(requirements, content) {
25042
+ var _a;
25043
+ const parsedCommitment = parseUseCalendarCommitmentContent(content);
25044
+ const existingConfiguredCalendars = normalizeConfiguredCalendars((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.useCalendars);
25045
+ if (parsedCommitment.calendar) {
25046
+ addConfiguredCalendarIfMissing(existingConfiguredCalendars, parsedCommitment.calendar);
25047
+ }
25048
+ const calendarsList = existingConfiguredCalendars.length > 0
25049
+ ? existingConfiguredCalendars
25050
+ .map((calendar) => [
25051
+ `- ${calendar.provider}: ${calendar.url}`,
25052
+ calendar.scopes.length > 0 ? ` scopes: ${calendar.scopes.join(', ')}` : '',
25053
+ ]
25054
+ .filter(Boolean)
25055
+ .join('\n'))
25056
+ .join('\n')
25057
+ : '- Calendar is resolved from runtime context';
25058
+ const extraInstructions = formatOptionalInstructionBlock('Calendar instructions', parsedCommitment.instructions);
25059
+ return this.appendToSystemMessage({
25060
+ ...requirements,
25061
+ tools: createUseCalendarTools(requirements.tools || []),
25062
+ _metadata: {
25063
+ ...requirements._metadata,
25064
+ useCalendar: true,
25065
+ useCalendars: existingConfiguredCalendars,
25066
+ },
25067
+ }, spaceTrim$1((block) => `
25068
+ Calendar tools:
25069
+ - You can inspect and manage events in configured calendars.
25070
+ - Supported operations include read, create, update, delete, invite guests, and reminders.
25071
+ - Configured calendars:
25072
+ ${block(calendarsList)}
25073
+ - USE CALENDAR credentials are read from wallet records (ACCESS_TOKEN, service "${UseCalendarWallet.service}", key "${UseCalendarWallet.key}").
25074
+ - If credentials are missing, ask user to connect calendar credentials in host UI and/or add them to wallet.
25075
+ ${block(extraInstructions)}
25076
+ `));
25077
+ }
25078
+ /**
25079
+ * Gets human-readable titles for tool functions provided by this commitment.
25080
+ */
25081
+ getToolTitles() {
25082
+ return getUseCalendarToolTitles();
25083
+ }
25084
+ /**
25085
+ * Gets calendar tool function implementations.
25086
+ */
25087
+ getToolFunctions() {
25088
+ return createUseCalendarToolFunctions();
25089
+ }
25090
+ }
25091
+ /**
25092
+ * Adds calendar into configured calendars list if it is not already present.
25093
+ *
25094
+ * @private function of UseCalendarCommitmentDefinition
25095
+ */
25096
+ function addConfiguredCalendarIfMissing(configuredCalendars, calendarReference) {
25097
+ if (configuredCalendars.some((calendar) => calendar.provider === calendarReference.provider && calendar.url === calendarReference.url)) {
25098
+ return;
25099
+ }
25100
+ configuredCalendars.push({
25101
+ provider: calendarReference.provider,
25102
+ url: calendarReference.url,
25103
+ calendarId: calendarReference.calendarId,
25104
+ scopes: [...calendarReference.scopes],
25105
+ ...(calendarReference.tokenRef ? { tokenRef: calendarReference.tokenRef } : {}),
25106
+ });
25107
+ }
25108
+ /**
25109
+ * Note: [💞] Ignore a discrepancy between file name and entity name
25110
+ */
25111
+
23873
25112
  /**
23874
25113
  * Lightweight email token matcher used for `USE EMAIL` first-line parsing.
23875
25114
  *
@@ -27737,6 +28976,7 @@ const COMMITMENT_REGISTRY = [
27737
28976
  new UseTimeoutCommitmentDefinition(),
27738
28977
  new UseTimeCommitmentDefinition(),
27739
28978
  new UseUserLocationCommitmentDefinition(),
28979
+ new UseCalendarCommitmentDefinition(),
27740
28980
  new UseEmailCommitmentDefinition(),
27741
28981
  new UsePopupCommitmentDefinition(),
27742
28982
  new UseImageGeneratorCommitmentDefinition('USE IMAGE GENERATOR'),
@@ -39490,6 +40730,14 @@ function parseAgentSource(agentSource) {
39490
40730
  });
39491
40731
  continue;
39492
40732
  }
40733
+ if (commitment.type === 'USE CALENDAR') {
40734
+ capabilities.push({
40735
+ type: 'calendar',
40736
+ label: 'Calendar',
40737
+ iconName: 'Calendar',
40738
+ });
40739
+ continue;
40740
+ }
39493
40741
  if (commitment.type === 'FROM') {
39494
40742
  const content = spaceTrim$2(commitment.content).split(/\r?\n/)[0] || '';
39495
40743
  if (content === 'Adam' || content === '' /* <- Note: Adam is implicit */) {