@promptbook/components 0.112.0-58 → 0.112.0-59

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.
package/esm/index.es.js CHANGED
@@ -40,7 +40,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
40
40
  * @generated
41
41
  * @see https://github.com/webgptorg/promptbook
42
42
  */
43
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-58';
43
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-59';
44
44
  /**
45
45
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
46
46
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -9530,6 +9530,49 @@ class BaseCommitmentDefinition {
9530
9530
  return this.appendToSystemMessage(requirements, commentSection);
9531
9531
  }
9532
9532
  }
9533
+ /**
9534
+ * Helper method to append a bullet point to an existing `## SectionTitle` section in the system
9535
+ * message, or to create a new section when it does not yet exist.
9536
+ *
9537
+ * Handles the case where the same commitment type appears multiple times in the book source and
9538
+ * all entries should be grouped under one shared heading rather than emitting a duplicate block.
9539
+ *
9540
+ * @param requirements - Current model requirements.
9541
+ * @param sectionTitle - Section title without the `##` prefix.
9542
+ * @param bulletContent - Bullet content without the leading `- ` prefix.
9543
+ * @returns Requirements with the bullet appended to the section.
9544
+ */
9545
+ appendBulletPointToSection(requirements, sectionTitle, bulletContent) {
9546
+ const sectionHeader = `## ${sectionTitle}`;
9547
+ const bullet = `- ${bulletContent}`;
9548
+ if (requirements.systemMessage.includes(sectionHeader)) {
9549
+ // Append bullet to end of existing section, before the next h2 heading or end of message
9550
+ const newSystemMessage = requirements.systemMessage.replace(new RegExp(`(## ${sectionTitle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n\\n)([\\s\\S]*?)(?=\\n\\n##|$)`), `$1$2\n${bullet}`);
9551
+ return { ...requirements, systemMessage: newSystemMessage };
9552
+ }
9553
+ return this.appendToSystemMessage(requirements, `${sectionHeader}\n\n${bullet}`, '\n\n');
9554
+ }
9555
+ /**
9556
+ * Helper method to replace an existing `## SectionTitle` section in the system message, or to
9557
+ * append a new one when the section does not yet exist.
9558
+ *
9559
+ * Use this when a commitment type can appear multiple times and each subsequent occurrence should
9560
+ * update the single shared section rather than appending a duplicate block.
9561
+ *
9562
+ * @param requirements - Current model requirements.
9563
+ * @param sectionTitle - Section title without the `##` prefix.
9564
+ * @param sectionContent - Full section content including the `## Title` header line.
9565
+ * @returns Requirements with the section replaced or appended.
9566
+ */
9567
+ replaceOrCreateSection(requirements, sectionTitle, sectionContent) {
9568
+ const sectionHeader = `## ${sectionTitle}`;
9569
+ if (requirements.systemMessage.includes(sectionHeader)) {
9570
+ // Replace all text from the heading until the next h2 heading or end of message
9571
+ const newSystemMessage = requirements.systemMessage.replace(new RegExp(`## ${sectionTitle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?(?=\\n\\n##|$)`), sectionContent);
9572
+ return { ...requirements, systemMessage: newSystemMessage };
9573
+ }
9574
+ return this.appendToSystemMessage(requirements, sectionContent, '\n\n');
9575
+ }
9533
9576
  /**
9534
9577
  * Gets tool function implementations provided by this commitment
9535
9578
  *
@@ -10009,20 +10052,16 @@ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
10009
10052
  if (!trimmedContent) {
10010
10053
  return requirements;
10011
10054
  }
10012
- // Get existing dictionary entries from metadata
10055
+ // Store the entry in metadata for debugging and inspection
10013
10056
  const existingDictionary = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
10014
- // Merge the new dictionary entry with existing entries
10015
10057
  const mergedDictionary = existingDictionary ? `${existingDictionary}\n${trimmedContent}` : trimmedContent;
10016
- // Store the merged dictionary in metadata for debugging and inspection
10017
10058
  const updatedMetadata = {
10018
10059
  ...requirements._metadata,
10019
10060
  DICTIONARY: mergedDictionary,
10020
10061
  };
10021
- // Create the dictionary section for the system message
10022
- // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
10023
- const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
10062
+ // Append each dictionary entry as a bullet point under ## Dictionary
10024
10063
  return {
10025
- ...this.appendToSystemMessage(requirements, dictionarySection),
10064
+ ...this.appendBulletPointToSection(requirements, 'Dictionary', trimmedContent),
10026
10065
  _metadata: updatedMetadata,
10027
10066
  };
10028
10067
  }
@@ -10536,10 +10575,10 @@ class GoalCommitmentDefinition extends BaseCommitmentDefinition {
10536
10575
  if (!trimmedContent) {
10537
10576
  return requirements;
10538
10577
  }
10539
- // Add goal to the system message
10540
- const goalSection = `Goal: ${trimmedContent}`;
10578
+ // Add goal as a proper h2 section to the system message
10579
+ const goalSection = `## Goal\n\n${trimmedContent}`;
10541
10580
  const requirementsWithGoal = this.appendToSystemMessage(requirements, goalSection, '\n\n');
10542
- return this.appendToPromptSuffix(requirementsWithGoal, goalSection);
10581
+ return this.appendToPromptSuffix(requirementsWithGoal, trimmedContent);
10543
10582
  }
10544
10583
  }
10545
10584
  // Note: [💞] Ignore a discrepancy between file name and entity name
@@ -11059,11 +11098,8 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
11059
11098
  if (!trimmedContent) {
11060
11099
  return requirements;
11061
11100
  }
11062
- // Add language rule to the system message
11063
- const languageSection = this.createSystemMessageSection('Language:', spaceTrim$1((block) => `
11064
- ${block(trimmedContent)}
11065
- <- You are speaking these languages in your responses to the user.
11066
- `));
11101
+ // Add language as a bullet under a ## Language section
11102
+ const languageSection = `## Language\n\n- Your language is ${trimmedContent}`;
11067
11103
  return this.appendToSystemMessage(requirements, languageSection, '\n\n');
11068
11104
  }
11069
11105
  }
@@ -11107,15 +11143,16 @@ const MemoryToolNames = {
11107
11143
  */
11108
11144
  function createMemorySystemMessage(extraInstructions) {
11109
11145
  return spaceTrim$1((block) => `
11110
- Memory:
11111
- - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
11112
- - You can use persistent user memory tools.
11113
- - Use "${MemoryToolNames.retrieve}" to load relevant memory before answering.
11114
- - Use "${MemoryToolNames.store}" to save stable user-specific facts that improve future help.
11115
- - Use "${MemoryToolNames.update}" to refresh an existing memory when the content changes.
11116
- - Use "${MemoryToolNames.delete}" to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
11117
- - Store concise memory items and avoid duplicates.
11118
- - Never claim memory was saved or loaded unless the tool confirms it.
11146
+ ## Memory
11147
+
11148
+ - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
11149
+ - You can use persistent user memory tools.
11150
+ - Use \`${MemoryToolNames.retrieve}\` to load relevant memory before answering.
11151
+ - Use \`${MemoryToolNames.store}\` to save stable user-specific facts that improve future help.
11152
+ - Use \`${MemoryToolNames.update}\` to refresh an existing memory when the content changes.
11153
+ - Use \`${MemoryToolNames.delete}\` to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
11154
+ - Store concise memory items and avoid duplicates.
11155
+ - Never claim memory was saved or loaded unless the tool confirms it.
11119
11156
  ${block(extraInstructions)}
11120
11157
  `);
11121
11158
  }
@@ -12037,10 +12074,8 @@ class MessageCommitmentDefinition extends BaseCommitmentDefinition {
12037
12074
  if (!trimmedContent) {
12038
12075
  return requirements;
12039
12076
  }
12040
- // Create message section for system message
12041
- const messageSection = `Previous Message: ${trimmedContent}`;
12042
12077
  // Messages represent conversation history and should be included for context
12043
- return this.appendToSystemMessage(requirements, messageSection, '\n\n');
12078
+ return this.appendBulletPointToSection(requirements, 'Previous messages', trimmedContent);
12044
12079
  }
12045
12080
  }
12046
12081
  // Note: [💞] Ignore a discrepancy between file name and entity name
@@ -13677,10 +13712,9 @@ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
13677
13712
  if (!trimmedContent) {
13678
13713
  return requirements;
13679
13714
  }
13680
- // Add rule to the system message
13681
- const ruleSection = `Rule: ${trimmedContent}`;
13682
- const requirementsWithRule = this.appendToSystemMessage(requirements, ruleSection, '\n\n');
13683
- return this.appendToPromptSuffix(requirementsWithRule, ruleSection);
13715
+ // Group all rules under a single ## Rules section as bullet points
13716
+ const requirementsWithRule = this.appendBulletPointToSection(requirements, 'Rules', trimmedContent);
13717
+ return this.appendToPromptSuffix(requirementsWithRule, `- ${trimmedContent}`);
13684
13718
  }
13685
13719
  }
13686
13720
  // Note: [💞] Ignore a discrepancy between file name and entity name
@@ -13916,10 +13950,8 @@ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
13916
13950
  if (!trimmedContent) {
13917
13951
  return requirements;
13918
13952
  }
13919
- // Create scenario section for system message
13920
- const scenarioSection = `Scenario: ${trimmedContent}`;
13921
13953
  // Scenarios provide important contextual information that affects behavior
13922
- return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
13954
+ return this.appendBulletPointToSection(requirements, 'Scenarios', trimmedContent);
13923
13955
  }
13924
13956
  }
13925
13957
  // Note: [💞] Ignore a discrepancy between file name and entity name
@@ -14302,8 +14334,8 @@ const teamToolTitles = {};
14302
14334
  * @private
14303
14335
  */
14304
14336
  const TEAM_SYSTEM_MESSAGE_GUIDANCE_LINES = [
14305
- '- If a teammate is relevant to the request, consult that teammate using the matching tool.',
14306
- '- Do not ask the user for information that a listed teammate can provide directly.',
14337
+ '- If a teammate is relevant to the request, consult that teammate using the matching tool.',
14338
+ '- Do not ask the user for information that a listed teammate can provide directly.',
14307
14339
  ];
14308
14340
  /**
14309
14341
  * Constant for remote agents by Url.
@@ -14431,7 +14463,7 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
14431
14463
  toolName: entry.toolName,
14432
14464
  });
14433
14465
  }
14434
- const teamSystemMessage = this.createSystemMessageSection('Teammates:', buildTeamSystemMessageBody(teamEntries));
14466
+ const teamSystemMessage = this.createSystemMessageSection('Teammates', buildTeamSystemMessageBody(teamEntries));
14435
14467
  return this.appendToSystemMessage({
14436
14468
  ...requirements,
14437
14469
  tools: updatedTools,
@@ -14921,36 +14953,38 @@ function createAggregatedUseCommitmentSystemMessage(type, additionalInstructions
14921
14953
  switch (type) {
14922
14954
  case 'USE TIME':
14923
14955
  return spaceTrim$1((block) => `
14924
- Time and date context:
14925
- - It is ${moment().format('MMMM YYYY')} now.
14926
- - If you need more precise current time information, use the tool "get_current_time".
14956
+ ## Time and date context
14957
+
14958
+ - It is ${moment().format('MMMM YYYY')} now.
14959
+ - If you need more precise current time information, use the tool \`get_current_time\`.
14927
14960
  ${block(formatOptionalInstructionBlock('Time instructions', combinedAdditionalInstructions))}
14928
14961
  `);
14929
14962
  case 'USE BROWSER':
14930
14963
  return spaceTrim$1((block) => `
14931
- You have access to browser tools to fetch and access content from the internet.
14932
- - Use "fetch_url_content" to retrieve content from specific URLs (webpages or documents) using scrapers.
14933
- - Use "run_browser" for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
14934
- When you need to know information from a specific website or document, use the fetch_url_content tool.
14964
+ ## Browser
14965
+
14966
+ - Use \`fetch_url_content\` to retrieve content from specific URLs (webpages or documents) using scrapers.
14967
+ - Use \`run_browser\` for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
14968
+ - When you need to know information from a specific website or document, use the tools provided.
14935
14969
  ${block(formatOptionalInstructionBlock('Browser instructions', combinedAdditionalInstructions))}
14936
14970
  `);
14937
14971
  case 'USE SEARCH ENGINE':
14938
14972
  return spaceTrim$1((block) => `
14939
- Tool:
14940
- - You have access to the web search engine via the tool "web_search".
14941
- - Use it to find up-to-date information or facts that you don't know.
14942
- - When you need to know some information from the internet, use the tool provided to you.
14943
- - Do not make up information when you can search for it.
14944
- - Do not tell the user you cannot search for information, YOU CAN.
14973
+ ## Web Search
14974
+
14975
+ - Use \`web_search\` to find up-to-date information or facts.
14976
+ - When you need to know some information from the internet, use the search tool provided.
14977
+ - Do not make up information when you can search for it.
14978
+ - Do not tell the user you cannot search for information, YOU CAN.
14945
14979
  ${block(formatOptionalInstructionBlock('Search instructions', combinedAdditionalInstructions))}
14946
14980
  `);
14947
14981
  case 'USE DEEPSEARCH':
14948
14982
  return spaceTrim$1((block) => `
14949
- Tool:
14950
- - You have access to DeepSearch via the tool "deep_search".
14951
- - Use it for broader research tasks that need multi-step investigation, comparison, or synthesis across multiple sources.
14952
- - Prefer it over quick search when the user asks for a well-grounded brief, report, or deeper investigation.
14953
- - Do not pretend you cannot research current information when this tool is available.
14983
+ ## Deep Research
14984
+
14985
+ - Use \`deep_search\` for broader research tasks that need multi-step investigation, comparison, or synthesis across multiple sources.
14986
+ - Prefer it over quick search when the user asks for a well-grounded brief, report, or deeper investigation.
14987
+ - Do not pretend you cannot research current information when this tool is available.
14954
14988
  ${block(formatOptionalInstructionBlock('DeepSearch instructions', combinedAdditionalInstructions))}
14955
14989
  `);
14956
14990
  }
@@ -15280,96 +15314,6 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
15280
15314
  }
15281
15315
  // Note: [💞] Ignore a discrepancy between file name and entity name
15282
15316
 
15283
- /**
15284
- * Base Google Calendar API URL.
15285
- *
15286
- * @private constant of callGoogleCalendarApi
15287
- */
15288
- const GOOGLE_CALENDAR_API_BASE_URL = 'https://www.googleapis.com/calendar/v3';
15289
- /**
15290
- * Runs one Google Calendar API request and parses JSON response payload.
15291
- *
15292
- * @private function of UseCalendarCommitmentDefinition
15293
- */
15294
- async function callGoogleCalendarApi(accessToken, options) {
15295
- const url = new URL(options.path, GOOGLE_CALENDAR_API_BASE_URL);
15296
- if (options.query) {
15297
- for (const [key, value] of Object.entries(options.query)) {
15298
- if (value && value.trim()) {
15299
- url.searchParams.set(key, value);
15300
- }
15301
- }
15302
- }
15303
- const response = await fetch(url.toString(), {
15304
- method: options.method,
15305
- headers: {
15306
- Authorization: `Bearer ${accessToken}`,
15307
- Accept: 'application/json',
15308
- 'Content-Type': 'application/json',
15309
- },
15310
- body: options.body ? JSON.stringify(options.body) : undefined,
15311
- });
15312
- const textPayload = await response.text();
15313
- const parsedPayload = tryParseJson$2(textPayload);
15314
- if (options.allowNotFound && response.status === 404) {
15315
- return null;
15316
- }
15317
- if (!response.ok) {
15318
- throw new Error(spaceTrim$1(`
15319
- Google Calendar API request failed (${response.status} ${response.statusText}):
15320
- ${extractGoogleCalendarApiErrorMessage(parsedPayload, textPayload)}
15321
- `));
15322
- }
15323
- return parsedPayload;
15324
- }
15325
- /**
15326
- * Parses raw text into JSON when possible.
15327
- *
15328
- * @private function of callGoogleCalendarApi
15329
- */
15330
- function tryParseJson$2(rawText) {
15331
- if (!rawText.trim()) {
15332
- return {};
15333
- }
15334
- try {
15335
- return JSON.parse(rawText);
15336
- }
15337
- catch (_a) {
15338
- return rawText;
15339
- }
15340
- }
15341
- /**
15342
- * Extracts a user-friendly Google Calendar API error message.
15343
- *
15344
- * @private function of callGoogleCalendarApi
15345
- */
15346
- function extractGoogleCalendarApiErrorMessage(parsedPayload, fallbackText) {
15347
- if (parsedPayload && typeof parsedPayload === 'object') {
15348
- const payload = parsedPayload;
15349
- const errorPayload = payload.error;
15350
- if (errorPayload && typeof errorPayload === 'object') {
15351
- const normalizedErrorPayload = errorPayload;
15352
- const message = typeof normalizedErrorPayload.message === 'string' ? normalizedErrorPayload.message : '';
15353
- const errors = Array.isArray(normalizedErrorPayload.errors) ? normalizedErrorPayload.errors : [];
15354
- const flattenedErrors = errors
15355
- .map((errorEntry) => {
15356
- if (!errorEntry || typeof errorEntry !== 'object') {
15357
- return '';
15358
- }
15359
- const normalizedErrorEntry = errorEntry;
15360
- const detailMessage = typeof normalizedErrorEntry.message === 'string' ? normalizedErrorEntry.message : '';
15361
- const reason = typeof normalizedErrorEntry.reason === 'string' ? normalizedErrorEntry.reason : '';
15362
- return [detailMessage, reason].filter(Boolean).join(' | ');
15363
- })
15364
- .filter(Boolean);
15365
- if (message || flattenedErrors.length > 0) {
15366
- return [message, ...flattenedErrors].filter(Boolean).join(' | ');
15367
- }
15368
- }
15369
- }
15370
- return fallbackText || 'Unknown Google Calendar API error';
15371
- }
15372
-
15373
15317
  /**
15374
15318
  * Hostnames accepted for Google Calendar references.
15375
15319
  *
@@ -15551,6 +15495,96 @@ function removeTokenFromLine(line, token) {
15551
15495
  }
15552
15496
  // Note: [💞] Ignore a discrepancy between file name and entity name
15553
15497
 
15498
+ /**
15499
+ * Base Google Calendar API URL.
15500
+ *
15501
+ * @private constant of callGoogleCalendarApi
15502
+ */
15503
+ const GOOGLE_CALENDAR_API_BASE_URL = 'https://www.googleapis.com/calendar/v3';
15504
+ /**
15505
+ * Runs one Google Calendar API request and parses JSON response payload.
15506
+ *
15507
+ * @private function of UseCalendarCommitmentDefinition
15508
+ */
15509
+ async function callGoogleCalendarApi(accessToken, options) {
15510
+ const url = new URL(options.path, GOOGLE_CALENDAR_API_BASE_URL);
15511
+ if (options.query) {
15512
+ for (const [key, value] of Object.entries(options.query)) {
15513
+ if (value && value.trim()) {
15514
+ url.searchParams.set(key, value);
15515
+ }
15516
+ }
15517
+ }
15518
+ const response = await fetch(url.toString(), {
15519
+ method: options.method,
15520
+ headers: {
15521
+ Authorization: `Bearer ${accessToken}`,
15522
+ Accept: 'application/json',
15523
+ 'Content-Type': 'application/json',
15524
+ },
15525
+ body: options.body ? JSON.stringify(options.body) : undefined,
15526
+ });
15527
+ const textPayload = await response.text();
15528
+ const parsedPayload = tryParseJson$2(textPayload);
15529
+ if (options.allowNotFound && response.status === 404) {
15530
+ return null;
15531
+ }
15532
+ if (!response.ok) {
15533
+ throw new Error(spaceTrim$1(`
15534
+ Google Calendar API request failed (${response.status} ${response.statusText}):
15535
+ ${extractGoogleCalendarApiErrorMessage(parsedPayload, textPayload)}
15536
+ `));
15537
+ }
15538
+ return parsedPayload;
15539
+ }
15540
+ /**
15541
+ * Parses raw text into JSON when possible.
15542
+ *
15543
+ * @private function of callGoogleCalendarApi
15544
+ */
15545
+ function tryParseJson$2(rawText) {
15546
+ if (!rawText.trim()) {
15547
+ return {};
15548
+ }
15549
+ try {
15550
+ return JSON.parse(rawText);
15551
+ }
15552
+ catch (_a) {
15553
+ return rawText;
15554
+ }
15555
+ }
15556
+ /**
15557
+ * Extracts a user-friendly Google Calendar API error message.
15558
+ *
15559
+ * @private function of callGoogleCalendarApi
15560
+ */
15561
+ function extractGoogleCalendarApiErrorMessage(parsedPayload, fallbackText) {
15562
+ if (parsedPayload && typeof parsedPayload === 'object') {
15563
+ const payload = parsedPayload;
15564
+ const errorPayload = payload.error;
15565
+ if (errorPayload && typeof errorPayload === 'object') {
15566
+ const normalizedErrorPayload = errorPayload;
15567
+ const message = typeof normalizedErrorPayload.message === 'string' ? normalizedErrorPayload.message : '';
15568
+ const errors = Array.isArray(normalizedErrorPayload.errors) ? normalizedErrorPayload.errors : [];
15569
+ const flattenedErrors = errors
15570
+ .map((errorEntry) => {
15571
+ if (!errorEntry || typeof errorEntry !== 'object') {
15572
+ return '';
15573
+ }
15574
+ const normalizedErrorEntry = errorEntry;
15575
+ const detailMessage = typeof normalizedErrorEntry.message === 'string' ? normalizedErrorEntry.message : '';
15576
+ const reason = typeof normalizedErrorEntry.reason === 'string' ? normalizedErrorEntry.reason : '';
15577
+ return [detailMessage, reason].filter(Boolean).join(' | ');
15578
+ })
15579
+ .filter(Boolean);
15580
+ if (message || flattenedErrors.length > 0) {
15581
+ return [message, ...flattenedErrors].filter(Boolean).join(' | ');
15582
+ }
15583
+ }
15584
+ }
15585
+ return fallbackText || 'Unknown Google Calendar API error';
15586
+ }
15587
+
15554
15588
  /**
15555
15589
  * Wallet metadata used by USE CALENDAR when resolving Google Calendar credentials.
15556
15590
  *
@@ -16451,18 +16485,20 @@ class UseCalendarCommitmentDefinition extends BaseCommitmentDefinition {
16451
16485
  if (parsedCommitment.calendar) {
16452
16486
  addConfiguredCalendarIfMissing(existingConfiguredCalendars, parsedCommitment.calendar);
16453
16487
  }
16454
- const calendarsList = existingConfiguredCalendars.length > 0
16455
- ? existingConfiguredCalendars
16456
- .map((calendar) => [
16457
- `- ${calendar.provider}: ${calendar.url}`,
16458
- calendar.scopes.length > 0 ? ` scopes: ${calendar.scopes.join(', ')}` : '',
16459
- ]
16460
- .filter(Boolean)
16461
- .join('\n'))
16462
- .join('\n')
16463
- : '- Calendar is resolved from runtime context';
16488
+ const calendarBullets = existingConfiguredCalendars.length > 0
16489
+ ? existingConfiguredCalendars.map((calendar) => `- ${calendar.provider}: ${calendar.url}`).join('\n')
16490
+ : '- Calendar is resolved from runtime context';
16464
16491
  const extraInstructions = formatOptionalInstructionBlock('Calendar instructions', parsedCommitment.instructions);
16465
- return this.appendToSystemMessage({
16492
+ const calendarSectionContent = spaceTrim$1((block) => `
16493
+ ## Calendar
16494
+
16495
+ - Use \`calendar_list_events\`, \`calendar_get_event\`, \`calendar_create_event\`, \`calendar_update_event\`, \`calendar_delete_event\`, and \`calendar_invite_guests\` to manage events in configured calendars.
16496
+ - Supported operations include read, create, update, delete, invite guests, and reminders.
16497
+ - Configured calendars:
16498
+ ${block(calendarBullets)}
16499
+ ${block(extraInstructions)}
16500
+ `);
16501
+ return this.replaceOrCreateSection({
16466
16502
  ...requirements,
16467
16503
  tools: createUseCalendarTools(requirements.tools || []),
16468
16504
  _metadata: {
@@ -16470,16 +16506,7 @@ class UseCalendarCommitmentDefinition extends BaseCommitmentDefinition {
16470
16506
  useCalendar: true,
16471
16507
  useCalendars: existingConfiguredCalendars,
16472
16508
  },
16473
- }, spaceTrim$1((block) => `
16474
- Calendar tools:
16475
- - You can inspect and manage events in configured calendars.
16476
- - Supported operations include read, create, update, delete, invite guests, and reminders.
16477
- - Configured calendars:
16478
- ${block(calendarsList)}
16479
- - USE CALENDAR credentials are read from wallet records (ACCESS_TOKEN, service "${UseCalendarWallet.service}", key "${UseCalendarWallet.key}").
16480
- - If credentials are missing, ask user to connect calendar credentials in host UI and/or add them to wallet.
16481
- ${block(extraInstructions)}
16482
- `));
16509
+ }, 'Calendar', calendarSectionContent);
16483
16510
  }
16484
16511
  /**
16485
16512
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -16816,18 +16843,6 @@ async function sendEmailViaBrowser(args, agentsServerUrl) {
16816
16843
  * @private internal USE EMAIL constant
16817
16844
  */
16818
16845
  const SEND_EMAIL_TOOL_NAME = 'send_email';
16819
- /**
16820
- * Wallet service used for SMTP credentials required by USE EMAIL.
16821
- *
16822
- * @private internal USE EMAIL constant
16823
- */
16824
- const USE_EMAIL_SMTP_WALLET_SERVICE = 'smtp';
16825
- /**
16826
- * Wallet key used for SMTP credentials required by USE EMAIL.
16827
- *
16828
- * @private internal USE EMAIL constant
16829
- */
16830
- const USE_EMAIL_SMTP_WALLET_KEY = 'use-email-smtp-credentials';
16831
16846
  /**
16832
16847
  * USE EMAIL commitment definition.
16833
16848
  *
@@ -16886,31 +16901,41 @@ class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
16886
16901
  `);
16887
16902
  }
16888
16903
  applyToAgentModelRequirements(requirements, content) {
16904
+ var _a;
16889
16905
  const parsedCommitment = parseUseEmailCommitmentContent(content);
16890
- const extraInstructions = formatOptionalInstructionBlock('Email instructions', parsedCommitment.instructions);
16891
- const senderInstruction = parsedCommitment.senderEmail
16892
- ? `- Default sender address from commitment: "${parsedCommitment.senderEmail}".`
16893
- : '';
16894
16906
  const updatedTools = addUseEmailTools(requirements.tools || []);
16895
- return this.appendToSystemMessage({
16907
+ // Collect all configured sender emails across multiple USE EMAIL commitments
16908
+ const existingSenders = Array.isArray((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.useEmailSenders)
16909
+ ? [...requirements._metadata.useEmailSenders]
16910
+ : [];
16911
+ if (parsedCommitment.senderEmail && !existingSenders.includes(parsedCommitment.senderEmail)) {
16912
+ existingSenders.push(parsedCommitment.senderEmail);
16913
+ }
16914
+ const senderBullets = existingSenders.length > 0
16915
+ ? existingSenders
16916
+ .map((email, index) => index === 0
16917
+ ? `- Default sender address: "${email}".`
16918
+ : `- Additional sender address: "${email}".`)
16919
+ .join('\n')
16920
+ : '';
16921
+ const extraInstructions = formatOptionalInstructionBlock('Email instructions', parsedCommitment.instructions);
16922
+ const emailSectionContent = spaceTrim$1((block) => `
16923
+ ## Emails
16924
+
16925
+ - Use \`${SEND_EMAIL_TOOL_NAME}\` to send outbound emails.
16926
+ ${block(senderBullets)}
16927
+ ${block(extraInstructions)}
16928
+ `);
16929
+ return this.replaceOrCreateSection({
16896
16930
  ...requirements,
16897
16931
  tools: updatedTools,
16898
16932
  _metadata: {
16899
16933
  ...requirements._metadata,
16900
16934
  useEmail: true,
16901
16935
  ...(parsedCommitment.senderEmail ? { useEmailSender: parsedCommitment.senderEmail } : {}),
16936
+ useEmailSenders: existingSenders,
16902
16937
  },
16903
- }, spaceTrim$1((block) => `
16904
- Email tool:
16905
- - Use "${SEND_EMAIL_TOOL_NAME}" to send outbound emails.
16906
- - Prefer \`message\` argument compatible with Promptbook \`Message\` type.
16907
- - Include subject in \`message.metadata.subject\` (or use legacy \`subject\` argument).
16908
- - USE EMAIL credentials are read from wallet records (ACCESS_TOKEN, service "${USE_EMAIL_SMTP_WALLET_SERVICE}", key "${USE_EMAIL_SMTP_WALLET_KEY}").
16909
- - Wallet secret must contain SMTP credentials in JSON format with fields \`host\`, \`port\`, \`secure\`, \`username\`, \`password\`.
16910
- - If credentials are missing, ask user to add wallet credentials.
16911
- ${block(senderInstruction)}
16912
- ${block(extraInstructions)}
16913
- `));
16938
+ }, 'Emails', emailSectionContent);
16914
16939
  }
16915
16940
  /**
16916
16941
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -16946,13 +16971,13 @@ function addUseEmailTools(existingTools) {
16946
16971
  ...existingTools,
16947
16972
  {
16948
16973
  name: SEND_EMAIL_TOOL_NAME,
16949
- description: 'Send an outbound email through configured SMTP credentials. Prefer providing Message-like payload in `message`.',
16974
+ description: 'Send an outbound email.',
16950
16975
  parameters: {
16951
16976
  type: 'object',
16952
16977
  properties: {
16953
16978
  message: {
16954
16979
  type: 'object',
16955
- description: 'Preferred input payload compatible with Promptbook Message type. Use metadata.subject for subject line.',
16980
+ description: 'Email payload. Use metadata.subject for the subject line.',
16956
16981
  },
16957
16982
  to: {
16958
16983
  type: 'string',
@@ -17056,13 +17081,14 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
17056
17081
  useImageGenerator: content || true,
17057
17082
  },
17058
17083
  }, spaceTrim$1((block) => `
17059
- Image generation:
17060
- - You do not generate images directly and you do not call any image tool.
17061
- - When the user asks for an image, include markdown notation in your message:
17062
- \`![<alt text>](?image-prompt=<prompt>)\`
17063
- - Keep \`<alt text>\` short and descriptive.
17064
- - Keep \`<prompt>\` detailed so the generated image matches the request.
17065
- - You can include normal explanatory text before and after the notation.
17084
+ ## Image generation
17085
+
17086
+ - You do not generate images directly and you do not call any image tool.
17087
+ - When the user asks for an image, include markdown notation in your message:
17088
+ \`![<alt text>](?image-prompt=<prompt>)\`
17089
+ - Keep \`<alt text>\` short and descriptive.
17090
+ - Keep \`<prompt>\` detailed so the generated image matches the request.
17091
+ - You can include normal explanatory text before and after the notation.
17066
17092
  ${block(extraInstructions)}
17067
17093
  `));
17068
17094
  }
@@ -17242,11 +17268,12 @@ class UsePopupCommitmentDefinition extends BaseCommitmentDefinition {
17242
17268
  usePopup: content || true,
17243
17269
  },
17244
17270
  }, spaceTrim$1((block) => `
17245
- Tool:
17246
- - You can open a popup window with a specific URL using the tool "open_popup".
17247
- - Use this when you want the user to see or interact with a specific website.
17271
+ ## Popup
17272
+
17273
+ - You can open a popup window with a specific URL using the tool \`open_popup\`.
17274
+ - Use this when you want the user to see or interact with a specific website.
17248
17275
  ${block(extraInstructions)}
17249
- `));
17276
+ `));
17250
17277
  }
17251
17278
  /**
17252
17279
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -17420,11 +17447,12 @@ class UsePrivacyCommitmentDefinition extends BaseCommitmentDefinition {
17420
17447
  usePrivacy: content || true,
17421
17448
  },
17422
17449
  }, spaceTrim$1((block) => `
17423
- Privacy mode:
17424
- - Use "${TURN_PRIVACY_ON_TOOL_NAME}" when the user asks for a private/sensitive conversation.
17425
- - This tool requests a UI confirmation dialog. Private mode is enabled only after user confirms.
17426
- - Current implementation uses the existing chat private mode (no chat persistence, memory persistence, or self-learning while active).
17427
- - Do not claim that end-to-end encryption is implemented yet.
17450
+ ## Privacy
17451
+
17452
+ - Use \`${TURN_PRIVACY_ON_TOOL_NAME}\` when the user asks for a private/sensitive conversation.
17453
+ - This tool requests a UI confirmation dialog. Private mode is enabled only after user confirms.
17454
+ - Current implementation uses the existing chat private mode (no chat persistence, memory persistence, or self-learning while active).
17455
+ - Do not claim that end-to-end encryption is implemented yet.
17428
17456
  ${block(extraInstructions)}
17429
17457
  `));
17430
17458
  }
@@ -19067,9 +19095,16 @@ class UseProjectCommitmentDefinition extends BaseCommitmentDefinition {
19067
19095
  }
19068
19096
  const existingConfiguredProjects = normalizeConfiguredProjects((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.useProjects);
19069
19097
  addConfiguredProjectIfMissing(existingConfiguredProjects, parsedCommitment.repository);
19070
- const repositoriesList = existingConfiguredProjects.map((project) => `- ${project.url}`).join('\n');
19071
19098
  const extraInstructions = formatOptionalInstructionBlock('Project instructions', parsedCommitment.instructions);
19072
- return this.appendToSystemMessage({
19099
+ const sectionContent = spaceTrim$1((block) => `
19100
+ - You can inspect and edit configured GitHub repositories using project tools.
19101
+ - Configured repositories:
19102
+ ${block(existingConfiguredProjects.map((project) => `- ${project.url}`).join('\n'))}
19103
+ - When a repository is not obvious from context, pass \`repository\` in tool arguments explicitly.
19104
+ - If credentials are missing, ask the user to connect their GitHub account in the host UI.
19105
+ ${block(extraInstructions)}
19106
+ `);
19107
+ return this.replaceOrCreateSection({
19073
19108
  ...requirements,
19074
19109
  tools: createUseProjectTools(requirements.tools || []),
19075
19110
  _metadata: {
@@ -19077,16 +19112,7 @@ class UseProjectCommitmentDefinition extends BaseCommitmentDefinition {
19077
19112
  useProject: true,
19078
19113
  useProjects: existingConfiguredProjects,
19079
19114
  },
19080
- }, spaceTrim$1((block) => `
19081
- Project tools:
19082
- - You can inspect and edit configured GitHub repositories using project tools.
19083
- - Configured repositories:
19084
- ${block(repositoriesList)}
19085
- - When a repository is not obvious from context, pass "repository" in tool arguments explicitly.
19086
- - USE PROJECT credentials are read from wallet records (ACCESS_TOKEN, service "${UseProjectWallet.service}", key "${UseProjectWallet.key}").
19087
- - If credentials are missing, ask the user to connect credentials in host UI and/or add them to wallet.
19088
- ${block(extraInstructions)}
19089
- `));
19115
+ }, 'GitHub repositories', sectionContent);
19090
19116
  }
19091
19117
  /**
19092
19118
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -19433,11 +19459,12 @@ class UseSpawnCommitmentDefinition extends BaseCommitmentDefinition {
19433
19459
  useSpawn: content || true,
19434
19460
  },
19435
19461
  }, spaceTrim$1((block) => `
19436
- Spawning agents:
19437
- - Use "${SPAWN_AGENT_TOOL_NAME}" only when user asks to create a persistent new agent.
19438
- - Pass full agent source in \`source\`.
19439
- - Keep \`source\` concise; the maximum accepted length is ${CREATE_AGENT_INPUT_SOURCE_MAX_LENGTH} characters.
19440
- - Do not add unknown fields in tool arguments.
19462
+ ## Spawning agents
19463
+
19464
+ - Use \`${SPAWN_AGENT_TOOL_NAME}\` only when user asks to create a persistent new agent.
19465
+ - Pass full agent source in \`source\`.
19466
+ - Keep \`source\` concise; the maximum accepted length is ${CREATE_AGENT_INPUT_SOURCE_MAX_LENGTH} characters.
19467
+ - Do not add unknown fields in tool arguments.
19441
19468
  ${block(extraInstructions)}
19442
19469
  `));
19443
19470
  }
@@ -19471,13 +19498,14 @@ class UseSpawnCommitmentDefinition extends BaseCommitmentDefinition {
19471
19498
  */
19472
19499
  function createTimeoutSystemMessage(extraInstructions) {
19473
19500
  return spaceTrim$1((block) => `
19474
- Timeout scheduling:
19475
- - Use "set_timeout" to wake this same chat thread in the future.
19476
- - Use "list_timeouts" to review timeout ids/details across all chats for the same user+agent scope.
19477
- - "cancel_timeout" accepts either one timeout id or \`allActive: true\` to cancel all active timeouts in this same user+agent scope.
19478
- - Use "update_timeout" to pause/resume, edit next run, edit recurrence, or update timeout payload details.
19479
- - When one timeout elapses, you will receive a new user-like message that explicitly says it is a timeout wake-up and includes the \`timeoutId\`.
19480
- - Do not claim a timer was set or cancelled unless the tool confirms it.
19501
+ ## Timeout scheduling
19502
+
19503
+ - Use \`set_timeout\` to wake this same chat thread in the future.
19504
+ - Use \`list_timeouts\` to review timeout ids/details across all chats for the same user+agent scope.
19505
+ - \`cancel_timeout\` accepts either one timeout id or \`allActive: true\` to cancel all active timeouts in this same user+agent scope.
19506
+ - Use \`update_timeout\` to pause/resume, edit next run, edit recurrence, or update timeout payload details.
19507
+ - When one timeout elapses, you will receive a new user-like message that explicitly says it is a timeout wake-up and includes the \`timeoutId\`.
19508
+ - Do not claim a timer was set or cancelled unless the tool confirms it.
19481
19509
  ${block(extraInstructions)}
19482
19510
  `);
19483
19511
  }
@@ -20577,10 +20605,11 @@ class UseUserLocationCommitmentDefinition extends BaseCommitmentDefinition {
20577
20605
  useUserLocation: content || true,
20578
20606
  },
20579
20607
  }, spaceTrim$1((block) => `
20580
- User location:
20581
- - Use "${GET_USER_LOCATION_TOOL_NAME}" only when location is needed for a better answer.
20582
- - If the tool returns "unavailable" or "permission-denied", ask user to share location or provide city manually.
20583
- - Do not invent coordinates or local facts when location is unavailable.
20608
+ ## User location
20609
+
20610
+ - Use \`${GET_USER_LOCATION_TOOL_NAME}\` only when location is needed for a better answer.
20611
+ - If the tool returns "unavailable" or "permission-denied", ask user to share location or provide city manually.
20612
+ - Do not invent coordinates or local facts when location is unavailable.
20584
20613
  ${block(extraInstructions)}
20585
20614
  `));
20586
20615
  }
@@ -36204,7 +36233,7 @@ function createExampleInteractionsContent(parseResult, samples) {
36204
36233
  if (examples.length === 0) {
36205
36234
  return null;
36206
36235
  }
36207
- return `Example interaction:\n\n${examples.join('\n\n')}`;
36236
+ return `## Sample of communication with the agent:\n\n${examples.join('\n\n')}`;
36208
36237
  }
36209
36238
  /**
36210
36239
  * Collects the individual lines used in the example interaction section.
@@ -36220,11 +36249,11 @@ function collectExampleInteractionLines(parseResult, samples) {
36220
36249
  const examples = [];
36221
36250
  const initialMessage = (_a = parseResult.commitments.find((commitment) => commitment.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
36222
36251
  if (initialMessage) {
36223
- examples.push(`Agent: ${initialMessage}`);
36252
+ examples.push(`**Agent:**\n${initialMessage}`);
36224
36253
  }
36225
36254
  if (samples && samples.length > 0) {
36226
36255
  for (const sample of samples) {
36227
- examples.push(`User: ${sample.question}\nAgent: ${sample.answer}`);
36256
+ examples.push(`**User:** ${sample.question}\n\n**Agent:**\n${sample.answer}`);
36228
36257
  }
36229
36258
  }
36230
36259
  return examples;