@promptbook/fake-llm 0.105.0-14 → 0.105.0-16

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 (26) hide show
  1. package/esm/index.es.js +506 -17
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/core.index.d.ts +10 -0
  4. package/esm/typings/src/_packages/types.index.d.ts +6 -0
  5. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +1 -1
  6. package/esm/typings/src/book-2.0/agent-source/parseTeamCommitment.d.ts +28 -0
  7. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +2 -7
  8. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +1 -6
  9. package/esm/typings/src/book-components/Chat/Chat/ClockIcon.d.ts +9 -0
  10. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +10 -37
  11. package/esm/typings/src/book-components/Chat/utils/getToolCallChipletText.d.ts +2 -5
  12. package/esm/typings/src/book-components/Chat/utils/toolCallParsing.d.ts +64 -0
  13. package/esm/typings/src/book-components/icons/SettingsIcon.d.ts +11 -0
  14. package/esm/typings/src/commitments/TEAM/TEAM.d.ts +45 -0
  15. package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +1 -0
  16. package/esm/typings/src/commitments/USE_TIME/USE_TIME.d.ts +2 -0
  17. package/esm/typings/src/commitments/_base/formatOptionalInstructionBlock.d.ts +6 -0
  18. package/esm/typings/src/commitments/index.d.ts +2 -1
  19. package/esm/typings/src/constants.d.ts +125 -0
  20. package/esm/typings/src/execution/PromptResult.d.ts +2 -19
  21. package/esm/typings/src/llm-providers/openai/OpenAiAssistantExecutionTools.d.ts +1 -0
  22. package/esm/typings/src/types/ToolCall.d.ts +37 -0
  23. package/esm/typings/src/version.d.ts +1 -1
  24. package/package.json +4 -2
  25. package/umd/index.umd.js +509 -19
  26. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -3,8 +3,9 @@ import { forTime } from 'waitasecond';
3
3
  import { randomBytes } from 'crypto';
4
4
  import { LoremIpsum } from 'lorem-ipsum';
5
5
  import 'path';
6
- import 'crypto-js';
7
- import 'crypto-js/enc-hex';
6
+ import { SHA256 } from 'crypto-js';
7
+ import hexEncoder from 'crypto-js/enc-hex';
8
+ import moment from 'moment';
8
9
 
9
10
  // ⚠️ WARNING: This code has been generated so that any manual changes will be overwritten
10
11
  /**
@@ -20,7 +21,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
20
21
  * @generated
21
22
  * @see https://github.com/webgptorg/promptbook
22
23
  */
23
- const PROMPTBOOK_ENGINE_VERSION = '0.105.0-14';
24
+ const PROMPTBOOK_ENGINE_VERSION = '0.105.0-16';
24
25
  /**
25
26
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
26
27
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2536,6 +2537,19 @@ class ParseError extends Error {
2536
2537
  * TODO: Maybe split `ParseError` and `ApplyError`
2537
2538
  */
2538
2539
 
2540
+ /**
2541
+ * Error thrown when a fetch request fails
2542
+ *
2543
+ * @public exported from `@promptbook/core`
2544
+ */
2545
+ class PromptbookFetchError extends Error {
2546
+ constructor(message) {
2547
+ super(message);
2548
+ this.name = 'PromptbookFetchError';
2549
+ Object.setPrototypeOf(this, PromptbookFetchError.prototype);
2550
+ }
2551
+ }
2552
+
2539
2553
  /**
2540
2554
  * Index of all javascript errors
2541
2555
  *
@@ -2563,6 +2577,18 @@ class ParseError extends Error {
2563
2577
  * Note: [💞] Ignore a discrepancy between file name and entity name
2564
2578
  */
2565
2579
 
2580
+ /**
2581
+ * Computes SHA-256 hash of the given object
2582
+ *
2583
+ * @public exported from `@promptbook/utils`
2584
+ */
2585
+ function computeHash(value) {
2586
+ return SHA256(hexEncoder.parse(spaceTrim$2(valueToString(value)))).toString( /* hex */);
2587
+ }
2588
+ /**
2589
+ * TODO: [🥬][🥬] Use this ACRY
2590
+ */
2591
+
2566
2592
  /**
2567
2593
  * Makes first letter of a string uppercase
2568
2594
  *
@@ -5856,6 +5882,432 @@ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
5856
5882
  * [💞] Ignore a discrepancy between file name and entity name
5857
5883
  */
5858
5884
 
5885
+ const urlRegex = /https?:\/\/[^\s]+/gi;
5886
+ const trailingPunctuationRegex = /[),.;!?]+$/;
5887
+ const clauseSeparators = ['.', '?', '!', ';', ','];
5888
+ const conjunctionSeparators = [' and ', ' or '];
5889
+ /**
5890
+ * Parses TEAM commitment content into teammates with instructions.
5891
+ *
5892
+ * @private
5893
+ */
5894
+ function parseTeamCommitmentContent(content, options = {}) {
5895
+ const { strict = false } = options;
5896
+ const lines = content
5897
+ .split('\n')
5898
+ .map((line) => line.trim())
5899
+ .filter(Boolean);
5900
+ const teammates = [];
5901
+ const seenUrls = new Set();
5902
+ for (const line of lines) {
5903
+ const matches = Array.from(line.matchAll(urlRegex));
5904
+ if (matches.length === 0) {
5905
+ if (strict) {
5906
+ throw new Error(`TEAM commitment expects at least one agent URL, got: "${line}"`);
5907
+ }
5908
+ continue;
5909
+ }
5910
+ for (const [matchIndex, match] of matches.entries()) {
5911
+ const rawUrl = match[0] || '';
5912
+ const cleanedUrl = rawUrl.replace(trailingPunctuationRegex, '');
5913
+ if (!isValidAgentUrl(cleanedUrl)) {
5914
+ if (strict) {
5915
+ throw new Error(`Invalid agent URL in TEAM commitment: "${cleanedUrl}"`);
5916
+ }
5917
+ continue;
5918
+ }
5919
+ if (seenUrls.has(cleanedUrl)) {
5920
+ continue;
5921
+ }
5922
+ seenUrls.add(cleanedUrl);
5923
+ const instructionContext = extractInstructionContext(line, matches, matchIndex);
5924
+ const instructions = normalizeInstructionText(instructionContext);
5925
+ const label = createTeammateLabel(cleanedUrl);
5926
+ teammates.push({
5927
+ url: cleanedUrl,
5928
+ label,
5929
+ instructions,
5930
+ });
5931
+ }
5932
+ }
5933
+ return teammates;
5934
+ }
5935
+ function extractInstructionContext(line, matches, matchIndex) {
5936
+ var _a;
5937
+ const match = matches[matchIndex];
5938
+ if (!match || match.index === undefined) {
5939
+ return line.trim();
5940
+ }
5941
+ const rawUrl = match[0] || '';
5942
+ const matchStart = match.index;
5943
+ const matchEnd = matchStart + rawUrl.length;
5944
+ const previousMatch = matches[matchIndex - 1];
5945
+ const nextMatch = matches[matchIndex + 1];
5946
+ const previousEnd = previousMatch && previousMatch.index !== undefined ? previousMatch.index + (((_a = previousMatch[0]) === null || _a === void 0 ? void 0 : _a.length) || 0) : 0;
5947
+ const nextStart = nextMatch && nextMatch.index !== undefined ? nextMatch.index : line.length;
5948
+ const rawPrefix = line.slice(previousEnd, matchStart);
5949
+ const rawSuffix = line.slice(matchEnd, nextStart);
5950
+ const prefix = trimAfterLastDelimiter(rawPrefix);
5951
+ const suffix = trimBeforeLastDelimiter(rawSuffix);
5952
+ if (normalizeInstructionText(suffix)) {
5953
+ return suffix;
5954
+ }
5955
+ if (normalizeInstructionText(prefix)) {
5956
+ return prefix;
5957
+ }
5958
+ return `${prefix} ${suffix}`.trim();
5959
+ }
5960
+ function trimAfterLastDelimiter(text) {
5961
+ const match = findLastDelimiter(text);
5962
+ if (!match) {
5963
+ return text;
5964
+ }
5965
+ return text.slice(match.index + match.length);
5966
+ }
5967
+ function trimBeforeLastDelimiter(text) {
5968
+ const cleaned = text.replace(/^[,;:]\s*/g, '');
5969
+ const match = findLastDelimiter(cleaned);
5970
+ if (!match || match.index <= 0) {
5971
+ return cleaned;
5972
+ }
5973
+ return cleaned.slice(0, match.index);
5974
+ }
5975
+ function findLastDelimiter(text) {
5976
+ let bestIndex = -1;
5977
+ let bestLength = 0;
5978
+ for (const separator of clauseSeparators) {
5979
+ const index = text.lastIndexOf(separator);
5980
+ if (index > bestIndex) {
5981
+ bestIndex = index;
5982
+ bestLength = separator.length;
5983
+ }
5984
+ }
5985
+ const lowerText = text.toLowerCase();
5986
+ for (const separator of conjunctionSeparators) {
5987
+ const index = lowerText.lastIndexOf(separator);
5988
+ if (index > bestIndex) {
5989
+ bestIndex = index;
5990
+ bestLength = separator.length;
5991
+ }
5992
+ }
5993
+ if (bestIndex === -1) {
5994
+ return null;
5995
+ }
5996
+ return { index: bestIndex, length: bestLength };
5997
+ }
5998
+ function normalizeInstructionText(text) {
5999
+ if (!text) {
6000
+ return '';
6001
+ }
6002
+ const withoutUrls = text.replace(urlRegex, '');
6003
+ let normalized = normalizeWhitespaces(withoutUrls).trim();
6004
+ normalized = normalized.replace(/^[,;:]\s*/g, '');
6005
+ normalized = normalized.replace(/^(and|or|the|a|an)\s+/i, '');
6006
+ normalized = normalized.replace(/\s*[,;:]\s*$/g, '');
6007
+ normalized = normalized.replace(/\s+(and|or)\s*$/i, '');
6008
+ normalized = normalizeWhitespaces(normalized).trim();
6009
+ return normalized;
6010
+ }
6011
+ function createTeammateLabel(url) {
6012
+ try {
6013
+ const parsed = new URL(url);
6014
+ const pathParts = parsed.pathname.split('/').filter(Boolean);
6015
+ const lastPart = pathParts[pathParts.length - 1] || parsed.hostname;
6016
+ const decoded = decodeURIComponent(lastPart);
6017
+ const spaced = decoded.replace(/[-_]+/g, ' ').trim();
6018
+ if (!spaced) {
6019
+ return parsed.hostname;
6020
+ }
6021
+ return spaced
6022
+ .split(' ')
6023
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
6024
+ .join(' ');
6025
+ }
6026
+ catch (error) {
6027
+ return url;
6028
+ }
6029
+ }
6030
+ /**
6031
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6032
+ */
6033
+
6034
+ /**
6035
+ * The built-in `fetch' function with a lightweight error handling wrapper as default fetch function used in Promptbook scrapers
6036
+ *
6037
+ * @public exported from `@promptbook/core`
6038
+ */
6039
+ const promptbookFetch = async (urlOrRequest, init) => {
6040
+ try {
6041
+ return await fetch(urlOrRequest, init);
6042
+ }
6043
+ catch (error) {
6044
+ assertsError(error);
6045
+ let url;
6046
+ if (typeof urlOrRequest === 'string') {
6047
+ url = urlOrRequest;
6048
+ }
6049
+ else if (urlOrRequest instanceof Request) {
6050
+ url = urlOrRequest.url;
6051
+ }
6052
+ throw new PromptbookFetchError(spaceTrim$2((block) => `
6053
+ Can not fetch "${url}"
6054
+
6055
+ Fetch error:
6056
+ ${block(error.message)}
6057
+
6058
+ `));
6059
+ }
6060
+ };
6061
+ /**
6062
+ * TODO: [🧠] Maybe rename because it is not used only for scrapers but also in `$getCompiledBook`
6063
+ */
6064
+
6065
+ const TEAM_TOOL_PREFIX = 'team_chat_';
6066
+ const teamToolFunctions = {};
6067
+ const teamToolTitles = {};
6068
+ /**
6069
+ * TEAM commitment definition
6070
+ *
6071
+ * The `TEAM` commitment defines teammates that the agent can consult via tools.
6072
+ *
6073
+ * Example usage in agent source:
6074
+ *
6075
+ * ```book
6076
+ * TEAM https://agents.ptbk.ik/agents/joe-green
6077
+ * TEAM You can talk with http://localhost:4440/agents/GMw67JN8TXxN7y to discuss the legal aspects.
6078
+ * ```
6079
+ *
6080
+ * @private [??] Maybe export the commitments through some package
6081
+ */
6082
+ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
6083
+ constructor() {
6084
+ super('TEAM');
6085
+ }
6086
+ /**
6087
+ * Short one-line description of TEAM.
6088
+ */
6089
+ get description() {
6090
+ return 'Enable the agent to consult teammate agents via dedicated tools.';
6091
+ }
6092
+ /**
6093
+ * Icon for this commitment.
6094
+ */
6095
+ get icon() {
6096
+ return '??';
6097
+ }
6098
+ /**
6099
+ * Markdown documentation for TEAM commitment.
6100
+ */
6101
+ get documentation() {
6102
+ return spaceTrim$1(`
6103
+ # TEAM
6104
+
6105
+ Registers teammate agents that the current agent can consult via tools.
6106
+
6107
+ ## Examples
6108
+
6109
+ \`\`\`book
6110
+ Legal Assistant
6111
+
6112
+ PERSONA An expert software developer
6113
+ TEAM You can talk with http://localhost:4440/agents/GMw67JN8TXxN7y to discuss the legal aspects.
6114
+ \`\`\`
6115
+ `);
6116
+ }
6117
+ applyToAgentModelRequirements(requirements, content) {
6118
+ var _a, _b;
6119
+ const trimmedContent = content.trim();
6120
+ if (!trimmedContent) {
6121
+ return requirements;
6122
+ }
6123
+ const teammates = parseTeamCommitmentContent(trimmedContent, { strict: true });
6124
+ if (teammates.length === 0) {
6125
+ return requirements;
6126
+ }
6127
+ const agentName = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.agentName) || 'Agent';
6128
+ const teamEntries = teammates.map((teammate) => ({
6129
+ toolName: createTeamToolName(teammate.url),
6130
+ teammate,
6131
+ agentName,
6132
+ }));
6133
+ for (const entry of teamEntries) {
6134
+ registerTeamTool(entry);
6135
+ }
6136
+ const existingTools = requirements.tools || [];
6137
+ const updatedTools = [...existingTools];
6138
+ for (const entry of teamEntries) {
6139
+ if (updatedTools.some((tool) => tool.name === entry.toolName)) {
6140
+ continue;
6141
+ }
6142
+ const instructionSuffix = entry.teammate.instructions
6143
+ ? `Use when: ${entry.teammate.instructions}`
6144
+ : 'Use when their expertise is needed.';
6145
+ updatedTools.push({
6146
+ name: entry.toolName,
6147
+ description: spaceTrim$1(`
6148
+ Consult teammate ${entry.teammate.label} (${entry.teammate.url}).
6149
+ ${instructionSuffix}
6150
+ `),
6151
+ parameters: {
6152
+ type: 'object',
6153
+ properties: {
6154
+ message: {
6155
+ type: 'string',
6156
+ description: 'Question or request to send to the teammate.',
6157
+ },
6158
+ context: {
6159
+ type: 'string',
6160
+ description: 'Optional background context for the teammate.',
6161
+ },
6162
+ },
6163
+ required: ['message'],
6164
+ },
6165
+ });
6166
+ }
6167
+ const existingTeammates = ((_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.teammates) || [];
6168
+ const updatedTeammates = [...existingTeammates];
6169
+ for (const entry of teamEntries) {
6170
+ if (updatedTeammates.some((existing) => existing.url === entry.teammate.url)) {
6171
+ continue;
6172
+ }
6173
+ updatedTeammates.push({
6174
+ url: entry.teammate.url,
6175
+ label: entry.teammate.label,
6176
+ instructions: entry.teammate.instructions || undefined,
6177
+ toolName: entry.toolName,
6178
+ });
6179
+ }
6180
+ const teamSystemMessage = spaceTrim$1((block) => `
6181
+ Teammates:
6182
+ ${block(teamEntries
6183
+ .map((entry) => {
6184
+ const whenToConsult = entry.teammate.instructions || 'Use when their expertise is needed.';
6185
+ return spaceTrim$1(() => `
6186
+ - ${entry.teammate.label} (${entry.teammate.url})
6187
+ - Tool: "${entry.toolName}"
6188
+ - When to consult: ${whenToConsult}
6189
+ `);
6190
+ })
6191
+ .join('\n'))}
6192
+ `);
6193
+ return this.appendToSystemMessage({
6194
+ ...requirements,
6195
+ tools: updatedTools,
6196
+ metadata: {
6197
+ ...requirements.metadata,
6198
+ teammates: updatedTeammates,
6199
+ },
6200
+ }, teamSystemMessage);
6201
+ }
6202
+ /**
6203
+ * Gets human-readable titles for tool functions provided by this commitment.
6204
+ */
6205
+ getToolTitles() {
6206
+ return { ...teamToolTitles };
6207
+ }
6208
+ /**
6209
+ * Gets tool function implementations for teammate tools.
6210
+ */
6211
+ getToolFunctions() {
6212
+ return { ...teamToolFunctions };
6213
+ }
6214
+ }
6215
+ function createTeamToolName(url) {
6216
+ const hash = computeHash(url).substring(0, 10);
6217
+ return `${TEAM_TOOL_PREFIX}${hash}`;
6218
+ }
6219
+ function registerTeamTool(entry) {
6220
+ teamToolFunctions[entry.toolName] = createTeamToolFunction(entry);
6221
+ teamToolTitles[entry.toolName] = `Consult ${entry.teammate.label}`;
6222
+ }
6223
+ function createTeamToolFunction(entry) {
6224
+ return async (args) => {
6225
+ const message = args.message || args.question || '';
6226
+ if (!message) {
6227
+ const result = {
6228
+ error: 'Message is required to contact teammate.',
6229
+ teammate: {
6230
+ url: entry.teammate.url,
6231
+ label: entry.teammate.label,
6232
+ instructions: entry.teammate.instructions,
6233
+ toolName: entry.toolName,
6234
+ },
6235
+ };
6236
+ return JSON.stringify(result);
6237
+ }
6238
+ const request = args.context ? `${message}\n\nContext:\n${args.context}` : message;
6239
+ let response = '';
6240
+ let error = null;
6241
+ try {
6242
+ response = await fetchTeammateResponse(entry.teammate.url, request);
6243
+ }
6244
+ catch (err) {
6245
+ error = err instanceof Error ? err.message : String(err);
6246
+ }
6247
+ const teammateReply = response || (error ? `Unable to reach teammate. Error: ${error}` : 'No response received.');
6248
+ const result = {
6249
+ teammate: {
6250
+ url: entry.teammate.url,
6251
+ label: entry.teammate.label,
6252
+ instructions: entry.teammate.instructions,
6253
+ toolName: entry.toolName,
6254
+ },
6255
+ request,
6256
+ response: teammateReply,
6257
+ error,
6258
+ conversation: [
6259
+ {
6260
+ sender: 'AGENT',
6261
+ name: entry.agentName,
6262
+ content: request,
6263
+ },
6264
+ {
6265
+ sender: 'TEAMMATE',
6266
+ name: entry.teammate.label,
6267
+ content: teammateReply,
6268
+ },
6269
+ ],
6270
+ };
6271
+ return JSON.stringify(result);
6272
+ };
6273
+ }
6274
+ async function fetchTeammateResponse(agentUrl, message) {
6275
+ const url = `${agentUrl.replace(/\/$/, '')}/api/chat`;
6276
+ const response = await promptbookFetch(url, {
6277
+ method: 'POST',
6278
+ headers: {
6279
+ 'Content-Type': 'application/json',
6280
+ },
6281
+ body: JSON.stringify({ message }),
6282
+ });
6283
+ if (!response.ok) {
6284
+ throw new Error(`Teammate request failed: ${response.status} ${response.statusText}`);
6285
+ }
6286
+ const rawText = await response.text();
6287
+ return stripToolCallLines(rawText).trim();
6288
+ }
6289
+ function stripToolCallLines(text) {
6290
+ const lines = text.replace(/\r\n/g, '\n').split('\n');
6291
+ return lines
6292
+ .filter((line) => {
6293
+ const trimmed = line.trim();
6294
+ if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {
6295
+ return true;
6296
+ }
6297
+ try {
6298
+ const parsed = JSON.parse(trimmed);
6299
+ return !('toolCalls' in parsed);
6300
+ }
6301
+ catch (_a) {
6302
+ return true;
6303
+ }
6304
+ })
6305
+ .join('\n');
6306
+ }
6307
+ /**
6308
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6309
+ */
6310
+
5859
6311
  /**
5860
6312
  * USE commitment definition
5861
6313
  *
@@ -6369,6 +6821,25 @@ class SerpSearchEngine {
6369
6821
  }
6370
6822
  }
6371
6823
 
6824
+ /**
6825
+ * @@@
6826
+ *
6827
+ * @private utility for commitments
6828
+ */
6829
+ function formatOptionalInstructionBlock(label, content) {
6830
+ const trimmedContent = spaceTrim$1(content);
6831
+ if (!trimmedContent) {
6832
+ return '';
6833
+ }
6834
+ return spaceTrim$1((block) => `
6835
+ - ${label}:
6836
+ ${block(trimmedContent
6837
+ .split('\n')
6838
+ .map((line) => `- ${line}`)
6839
+ .join('\n'))}
6840
+ `);
6841
+ }
6842
+
6372
6843
  /**
6373
6844
  * USE SEARCH ENGINE commitment definition
6374
6845
  *
@@ -6390,6 +6861,9 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
6390
6861
  constructor() {
6391
6862
  super('USE SEARCH ENGINE', ['USE SEARCH']);
6392
6863
  }
6864
+ get requiresContent() {
6865
+ return false;
6866
+ }
6393
6867
  /**
6394
6868
  * Short one-line description of USE SEARCH ENGINE.
6395
6869
  */
@@ -6438,6 +6912,7 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
6438
6912
  `);
6439
6913
  }
6440
6914
  applyToAgentModelRequirements(requirements, content) {
6915
+ const extraInstructions = formatOptionalInstructionBlock('Search instructions', content);
6441
6916
  // Get existing tools array or create new one
6442
6917
  const existingTools = requirements.tools || [];
6443
6918
  // Add 'web_search' to tools if not already present
@@ -6496,13 +6971,14 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
6496
6971
  ...requirements.metadata,
6497
6972
  useSearchEngine: content || true,
6498
6973
  },
6499
- }, spaceTrim$1(`
6500
- Tools:
6501
- You have access to the web search engine via the tool "web_search".
6502
- Use it to find up-to-date information or facts that you don't know.
6503
- When you need to know some information from the internet, use the tool provided to you.
6504
- Do not make up information when you can search for it.
6505
- Do not tell the user you cannot search for information, YOU CAN.
6974
+ }, spaceTrim$1((block) => `
6975
+ Tool:
6976
+ - You have access to the web search engine via the tool "web_search".
6977
+ - Use it to find up-to-date information or facts that you don't know.
6978
+ - When you need to know some information from the internet, use the tool provided to you.
6979
+ - Do not make up information when you can search for it.
6980
+ - Do not tell the user you cannot search for information, YOU CAN.
6981
+ ${block(extraInstructions)}
6506
6982
  `));
6507
6983
  }
6508
6984
  /**
@@ -6554,6 +7030,7 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
6554
7030
  *
6555
7031
  * ```book
6556
7032
  * USE TIME
7033
+ * USE TIME Prefer the user's local timezone.
6557
7034
  * ```
6558
7035
  *
6559
7036
  * @private [🪔] Maybe export the commitments through some package
@@ -6562,6 +7039,9 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
6562
7039
  constructor() {
6563
7040
  super('USE TIME', ['CURRENT TIME', 'TIME', 'DATE']);
6564
7041
  }
7042
+ get requiresContent() {
7043
+ return false;
7044
+ }
6565
7045
  /**
6566
7046
  * Short one-line description of USE TIME.
6567
7047
  */
@@ -6588,6 +7068,7 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
6588
7068
  - This tool won't receive any input.
6589
7069
  - It outputs the current date and time as an ISO 8601 string.
6590
7070
  - Allows the agent to answer questions about the current time or date.
7071
+ - The content following \`USE TIME\` is an arbitrary text that the agent should know (e.g. timezone preference).
6591
7072
 
6592
7073
  ## Examples
6593
7074
 
@@ -6597,9 +7078,17 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
6597
7078
  PERSONA You are a helpful assistant who knows the current time.
6598
7079
  USE TIME
6599
7080
  \`\`\`
7081
+
7082
+ \`\`\`book
7083
+ Travel Assistant
7084
+
7085
+ PERSONA You help travelers with planning.
7086
+ USE TIME Prefer the user's local timezone.
7087
+ \`\`\`
6600
7088
  `);
6601
7089
  }
6602
7090
  applyToAgentModelRequirements(requirements, content) {
7091
+ const extraInstructions = formatOptionalInstructionBlock('Time instructions', content);
6603
7092
  // Get existing tools array or create new one
6604
7093
  const existingTools = requirements.tools || [];
6605
7094
  // Add 'get_current_time' to tools if not already present
@@ -6630,13 +7119,12 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
6630
7119
  metadata: {
6631
7120
  ...requirements.metadata,
6632
7121
  },
6633
- }, spaceTrim$1(`
6634
- Tool:
6635
- You have access to the current date and time via the tool "get_current_time".
6636
- Use it to answer questions about the current date and time.
6637
- When you need to know the current date or time, use the tool provided to you.
6638
- Do not make up the current date or time; always use the tool to get accurate information.
6639
- `));
7122
+ }, spaceTrim$1((block) => `
7123
+ Time and date context:
7124
+ - It is ${moment().format('MMMM YYYY')} now.
7125
+ - If you need more precise current time information, use the tool "get_current_time".
7126
+ ${block(extraInstructions)}
7127
+ `));
6640
7128
  }
6641
7129
  /**
6642
7130
  * Gets human-readable titles for tool functions provided by this commitment.
@@ -6814,6 +7302,7 @@ const COMMITMENT_REGISTRY = [
6814
7302
  new DictionaryCommitmentDefinition(),
6815
7303
  new OpenCommitmentDefinition(),
6816
7304
  new ClosedCommitmentDefinition(),
7305
+ new TeamCommitmentDefinition(),
6817
7306
  new UseBrowserCommitmentDefinition(),
6818
7307
  new UseSearchEngineCommitmentDefinition(),
6819
7308
  new UseTimeCommitmentDefinition(),