@promptbook/core 0.110.0-7 → 0.110.0-9

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 +467 -107
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/components.index.d.ts +2 -0
  4. package/esm/typings/src/_packages/types.index.d.ts +4 -0
  5. package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +22 -21
  6. package/esm/typings/src/book-components/Chat/AgentChip/AgentChip.d.ts +5 -1
  7. package/esm/typings/src/book-components/Chat/Chat/ChatInputArea.d.ts +1 -0
  8. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +4 -0
  9. package/esm/typings/src/book-components/Chat/Chat/ChatMessageList.d.ts +1 -0
  10. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +15 -0
  11. package/esm/typings/src/book-components/Chat/Chat/ChatSoundToggle.d.ts +19 -0
  12. package/esm/typings/src/book-components/Chat/LlmChat/LlmChatProps.d.ts +10 -1
  13. package/esm/typings/src/commitments/_base/BaseCommitmentDefinition.d.ts +9 -0
  14. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.test.d.ts +1 -0
  15. package/esm/typings/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +39 -0
  16. package/esm/typings/src/types/LlmToolDefinition.d.ts +1 -0
  17. package/esm/typings/src/types/ModelRequirements.d.ts +9 -0
  18. package/esm/typings/src/utils/DEFAULT_THINKING_MESSAGES.d.ts +8 -0
  19. package/esm/typings/src/utils/knowledge/inlineKnowledgeSource.d.ts +38 -0
  20. package/esm/typings/src/utils/knowledge/inlineKnowledgeSource.test.d.ts +1 -0
  21. package/esm/typings/src/utils/language/getBrowserPreferredSpeechRecognitionLanguage.d.ts +35 -0
  22. package/esm/typings/src/utils/toolCalls/getToolCallIdentity.d.ts +10 -0
  23. package/esm/typings/src/version.d.ts +1 -1
  24. package/package.json +1 -1
  25. package/umd/index.umd.js +467 -107
  26. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -28,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.110.0-7';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.110.0-9';
32
32
  /**
33
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -7657,11 +7657,14 @@ async function preparePersona(personaDescription, tools, options) {
7657
7657
  function createEmptyAgentModelRequirements() {
7658
7658
  return {
7659
7659
  systemMessage: '',
7660
+ promptSuffix: '',
7660
7661
  // modelName: 'gpt-5',
7661
7662
  modelName: 'gemini-2.5-flash-lite',
7662
7663
  temperature: 0.7,
7663
7664
  topP: 0.9,
7664
7665
  topK: 50,
7666
+ parentAgentUrl: null,
7667
+ isClosed: false,
7665
7668
  };
7666
7669
  }
7667
7670
  /**
@@ -7778,6 +7781,28 @@ class BaseCommitmentDefinition {
7778
7781
  return currentMessage + separator + content;
7779
7782
  });
7780
7783
  }
7784
+ /**
7785
+ * Helper method to create a new requirements object with updated prompt suffix
7786
+ */
7787
+ updatePromptSuffix(requirements, contentUpdate) {
7788
+ const newSuffix = typeof contentUpdate === 'string' ? contentUpdate : contentUpdate(requirements.promptSuffix);
7789
+ return {
7790
+ ...requirements,
7791
+ promptSuffix: newSuffix,
7792
+ };
7793
+ }
7794
+ /**
7795
+ * Helper method to append content to the prompt suffix
7796
+ * Default separator is a single newline for bullet lists.
7797
+ */
7798
+ appendToPromptSuffix(requirements, content, separator = '\n') {
7799
+ return this.updatePromptSuffix(requirements, (currentSuffix) => {
7800
+ if (!currentSuffix.trim()) {
7801
+ return content;
7802
+ }
7803
+ return `${currentSuffix}${separator}${content}`;
7804
+ });
7805
+ }
7781
7806
  /**
7782
7807
  * Helper method to add a comment section to the system message
7783
7808
  * Comments are lines starting with # that will be removed from the final system message
@@ -7955,13 +7980,9 @@ class ClosedCommitmentDefinition extends BaseCommitmentDefinition {
7955
7980
  `);
7956
7981
  }
7957
7982
  applyToAgentModelRequirements(requirements, _content) {
7958
- const updatedMetadata = {
7959
- ...requirements.metadata,
7960
- isClosed: true,
7961
- };
7962
7983
  return {
7963
7984
  ...requirements,
7964
- metadata: updatedMetadata,
7985
+ isClosed: true,
7965
7986
  };
7966
7987
  }
7967
7988
  }
@@ -8239,12 +8260,12 @@ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
8239
8260
  return requirements;
8240
8261
  }
8241
8262
  // Get existing dictionary entries from metadata
8242
- const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
8263
+ const existingDictionary = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
8243
8264
  // Merge the new dictionary entry with existing entries
8244
8265
  const mergedDictionary = existingDictionary ? `${existingDictionary}\n${trimmedContent}` : trimmedContent;
8245
8266
  // Store the merged dictionary in metadata for debugging and inspection
8246
8267
  const updatedMetadata = {
8247
- ...requirements.metadata,
8268
+ ...requirements._metadata,
8248
8269
  DICTIONARY: mergedDictionary,
8249
8270
  };
8250
8271
  // Create the dictionary section for the system message
@@ -8252,7 +8273,7 @@ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
8252
8273
  const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
8253
8274
  return {
8254
8275
  ...this.appendToSystemMessage(requirements, dictionarySection),
8255
- metadata: updatedMetadata,
8276
+ _metadata: updatedMetadata,
8256
8277
  };
8257
8278
  }
8258
8279
  }
@@ -10697,10 +10718,7 @@ class FromCommitmentDefinition extends BaseCommitmentDefinition {
10697
10718
  applyToAgentModelRequirements(requirements, content) {
10698
10719
  const trimmedContent = content.trim();
10699
10720
  if (!trimmedContent) {
10700
- return {
10701
- ...requirements,
10702
- parentAgentUrl: undefined,
10703
- };
10721
+ return requirements;
10704
10722
  }
10705
10723
  if (trimmedContent.toUpperCase() === 'VOID' ||
10706
10724
  trimmedContent.toUpperCase() === 'NULL' ||
@@ -10914,6 +10932,136 @@ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
10914
10932
  * Note: [💞] Ignore a discrepancy between file name and entity name
10915
10933
  */
10916
10934
 
10935
+ /**
10936
+ * @@@
10937
+ *
10938
+ * @private thing of inline knowledge
10939
+ */
10940
+ const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';
10941
+ /**
10942
+ * @@@
10943
+ *
10944
+ * @private thing of inline knowledge
10945
+ */
10946
+ const INLINE_KNOWLEDGE_EXTENSION = '.txt';
10947
+ /**
10948
+ * @@@
10949
+ *
10950
+ * @private thing of inline knowledge
10951
+ */
10952
+ const DATA_URL_PREFIX = 'data:';
10953
+ /**
10954
+ * @@@
10955
+ *
10956
+ * @private thing of inline knowledge
10957
+ */
10958
+ function getFirstNonEmptyLine(content) {
10959
+ const lines = content.split(/\r?\n/);
10960
+ for (const line of lines) {
10961
+ const trimmed = line.trim();
10962
+ if (trimmed) {
10963
+ return trimmed;
10964
+ }
10965
+ }
10966
+ return null;
10967
+ }
10968
+ /**
10969
+ * @@@
10970
+ *
10971
+ * @private thing of inline knowledge
10972
+ */
10973
+ function deriveBaseFilename(content) {
10974
+ const firstLine = getFirstNonEmptyLine(content);
10975
+ if (!firstLine) {
10976
+ return INLINE_KNOWLEDGE_BASE_NAME;
10977
+ }
10978
+ const normalized = normalizeToKebabCase(firstLine);
10979
+ return normalized || INLINE_KNOWLEDGE_BASE_NAME;
10980
+ }
10981
+ /**
10982
+ * Creates a data URL that represents the inline knowledge content as a text file.
10983
+ *
10984
+ * @private thing of inline knowledge
10985
+ */
10986
+ function createInlineKnowledgeSourceFile(content) {
10987
+ const trimmedContent = content.trim();
10988
+ const baseName = deriveBaseFilename(trimmedContent);
10989
+ const filename = `${baseName}${INLINE_KNOWLEDGE_EXTENSION}`;
10990
+ const mimeType = 'text/plain';
10991
+ const base64 = Buffer.from(trimmedContent, 'utf-8').toString('base64');
10992
+ const encodedFilename = encodeURIComponent(filename);
10993
+ const url = `${DATA_URL_PREFIX}${mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
10994
+ return {
10995
+ filename,
10996
+ mimeType,
10997
+ url,
10998
+ };
10999
+ }
11000
+ /**
11001
+ * Checks whether the provided source string is a data URL that can be decoded.
11002
+ *
11003
+ * @private thing of inline knowledge
11004
+ */
11005
+ function isDataUrlKnowledgeSource(source) {
11006
+ return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);
11007
+ }
11008
+ /**
11009
+ * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.
11010
+ *
11011
+ * @private thing of inline knowledge
11012
+ */
11013
+ function parseDataUrlKnowledgeSource(source) {
11014
+ if (!isDataUrlKnowledgeSource(source)) {
11015
+ return null;
11016
+ }
11017
+ const commaIndex = source.indexOf(',');
11018
+ if (commaIndex === -1) {
11019
+ return null;
11020
+ }
11021
+ const header = source.slice(DATA_URL_PREFIX.length, commaIndex);
11022
+ const payload = source.slice(commaIndex + 1);
11023
+ const tokens = header.split(';');
11024
+ const mediaType = tokens[0] || 'text/plain';
11025
+ let filename = `${INLINE_KNOWLEDGE_BASE_NAME}${INLINE_KNOWLEDGE_EXTENSION}`;
11026
+ let isBase64 = false;
11027
+ for (let i = 1; i < tokens.length; i++) {
11028
+ const token = tokens[i];
11029
+ if (!token) {
11030
+ continue;
11031
+ }
11032
+ if (token.toLowerCase() === 'base64') {
11033
+ isBase64 = true;
11034
+ continue;
11035
+ }
11036
+ const [key, value] = token.split('=');
11037
+ if (key === 'name' && value !== undefined) {
11038
+ try {
11039
+ filename = decodeURIComponent(value);
11040
+ }
11041
+ catch (_a) {
11042
+ filename = value;
11043
+ }
11044
+ }
11045
+ }
11046
+ if (!isBase64) {
11047
+ return null;
11048
+ }
11049
+ try {
11050
+ const buffer = Buffer.from(payload, 'base64');
11051
+ return {
11052
+ buffer,
11053
+ filename,
11054
+ mimeType: mediaType,
11055
+ };
11056
+ }
11057
+ catch (_b) {
11058
+ return null;
11059
+ }
11060
+ }
11061
+ /**
11062
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11063
+ */
11064
+
10917
11065
  /**
10918
11066
  * KNOWLEDGE commitment definition
10919
11067
  *
@@ -11012,9 +11160,13 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
11012
11160
  return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
11013
11161
  }
11014
11162
  else {
11015
- // Direct text knowledge - add to system message
11016
- const knowledgeSection = `Knowledge: ${trimmedContent}`;
11017
- return this.appendToSystemMessage(requirements, knowledgeSection, '\n\n');
11163
+ const inlineSource = createInlineKnowledgeSourceFile(trimmedContent);
11164
+ const updatedRequirements = {
11165
+ ...requirements,
11166
+ knowledgeSources: [...(requirements.knowledgeSources || []), inlineSource.url],
11167
+ };
11168
+ const knowledgeInfo = `Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`;
11169
+ return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
11018
11170
  }
11019
11171
  }
11020
11172
  }
@@ -11261,16 +11413,16 @@ class AgentMessageCommitmentDefinition extends BaseCommitmentDefinition {
11261
11413
  // and typically doesn't need to be added to the system prompt or model requirements directly.
11262
11414
  // It is extracted separately for the chat interface.
11263
11415
  var _a;
11264
- const pendingUserMessage = (_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
11416
+ const pendingUserMessage = (_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
11265
11417
  if (pendingUserMessage) {
11266
11418
  const newSample = { question: pendingUserMessage, answer: content };
11267
11419
  const newSamples = [...(requirements.samples || []), newSample];
11268
- const newMetadata = { ...requirements.metadata };
11420
+ const newMetadata = { ...requirements._metadata };
11269
11421
  delete newMetadata.pendingUserMessage;
11270
11422
  return {
11271
11423
  ...requirements,
11272
11424
  samples: newSamples,
11273
- metadata: newMetadata,
11425
+ _metadata: newMetadata,
11274
11426
  };
11275
11427
  }
11276
11428
  return requirements;
@@ -11518,8 +11670,8 @@ class UserMessageCommitmentDefinition extends BaseCommitmentDefinition {
11518
11670
  applyToAgentModelRequirements(requirements, content) {
11519
11671
  return {
11520
11672
  ...requirements,
11521
- metadata: {
11522
- ...requirements.metadata,
11673
+ _metadata: {
11674
+ ...requirements._metadata,
11523
11675
  pendingUserMessage: content,
11524
11676
  },
11525
11677
  };
@@ -12377,11 +12529,7 @@ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
12377
12529
  if (trimmedContent === '') {
12378
12530
  return requirements;
12379
12531
  }
12380
- // Return requirements with updated notes but no changes to system message
12381
- return {
12382
- ...requirements,
12383
- notes: [...(requirements.notes || []), trimmedContent],
12384
- };
12532
+ return requirements;
12385
12533
  }
12386
12534
  }
12387
12535
  /**
@@ -12443,12 +12591,12 @@ class OpenCommitmentDefinition extends BaseCommitmentDefinition {
12443
12591
  // Since OPEN is default, we can just ensure isClosed is false
12444
12592
  // But to be explicit we can set it
12445
12593
  const updatedMetadata = {
12446
- ...requirements.metadata,
12594
+ ...requirements._metadata,
12447
12595
  isClosed: false,
12448
12596
  };
12449
12597
  return {
12450
12598
  ...requirements,
12451
- metadata: updatedMetadata,
12599
+ _metadata: updatedMetadata,
12452
12600
  };
12453
12601
  }
12454
12602
  }
@@ -12529,7 +12677,7 @@ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
12529
12677
  return requirements;
12530
12678
  }
12531
12679
  // Get existing persona content from metadata
12532
- const existingPersonaContent = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
12680
+ const existingPersonaContent = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.PERSONA) || '';
12533
12681
  // Merge the new content with existing persona content
12534
12682
  // When multiple PERSONA commitments exist, they are merged into one
12535
12683
  const mergedPersonaContent = existingPersonaContent
@@ -12537,12 +12685,12 @@ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
12537
12685
  : trimmedContent;
12538
12686
  // Store the merged persona content in metadata for debugging and inspection
12539
12687
  const updatedMetadata = {
12540
- ...requirements.metadata,
12688
+ ...requirements._metadata,
12541
12689
  PERSONA: mergedPersonaContent,
12542
12690
  };
12543
12691
  // Get the agent name from metadata (which should contain the first line of agent source)
12544
12692
  // If not available, extract from current system message as fallback
12545
- let agentName = (_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.agentName;
12693
+ let agentName = (_b = requirements._metadata) === null || _b === void 0 ? void 0 : _b.agentName;
12546
12694
  if (!agentName) {
12547
12695
  // Fallback: extract from current system message
12548
12696
  const currentMessage = requirements.systemMessage.trim();
@@ -12589,7 +12737,7 @@ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
12589
12737
  return {
12590
12738
  ...requirements,
12591
12739
  systemMessage: newSystemMessage,
12592
- metadata: updatedMetadata,
12740
+ _metadata: updatedMetadata,
12593
12741
  };
12594
12742
  }
12595
12743
  }
@@ -12672,7 +12820,16 @@ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
12672
12820
  }
12673
12821
  // Add rule to the system message
12674
12822
  const ruleSection = `Rule: ${trimmedContent}`;
12675
- return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
12823
+ const requirementsWithRule = this.appendToSystemMessage(requirements, ruleSection, '\n\n');
12824
+ const ruleLines = trimmedContent
12825
+ .split(/\r?\n/)
12826
+ .map((line) => line.trim())
12827
+ .filter(Boolean)
12828
+ .map((line) => `- ${line}`);
12829
+ if (ruleLines.length === 0) {
12830
+ return requirementsWithRule;
12831
+ }
12832
+ return this.appendToPromptSuffix(requirementsWithRule, ruleLines.join('\n'));
12676
12833
  }
12677
12834
  }
12678
12835
  /**
@@ -13178,7 +13335,7 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
13178
13335
  if (teammates.length === 0) {
13179
13336
  return requirements;
13180
13337
  }
13181
- const agentName = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.agentName) || 'Agent';
13338
+ const agentName = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.agentName) || 'Agent';
13182
13339
  const teamEntries = teammates.map((teammate) => ({
13183
13340
  toolName: createTeamToolName(teammate.url),
13184
13341
  teammate,
@@ -13218,7 +13375,7 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
13218
13375
  },
13219
13376
  });
13220
13377
  }
13221
- const existingTeammates = ((_b = requirements.metadata) === null || _b === void 0 ? void 0 : _b.teammates) || [];
13378
+ const existingTeammates = ((_b = requirements._metadata) === null || _b === void 0 ? void 0 : _b.teammates) || [];
13222
13379
  const updatedTeammates = [...existingTeammates];
13223
13380
  for (const entry of teamEntries) {
13224
13381
  if (updatedTeammates.some((existing) => existing.url === entry.teammate.url)) {
@@ -13247,8 +13404,8 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
13247
13404
  return this.appendToSystemMessage({
13248
13405
  ...requirements,
13249
13406
  tools: updatedTools,
13250
- metadata: {
13251
- ...requirements.metadata,
13407
+ _metadata: {
13408
+ ...requirements._metadata,
13252
13409
  teammates: updatedTeammates,
13253
13410
  },
13254
13411
  }, teamSystemMessage);
@@ -13480,7 +13637,7 @@ class TemplateCommitmentDefinition extends BaseCommitmentDefinition {
13480
13637
  if (!trimmedContent) {
13481
13638
  // Store template mode flag in metadata
13482
13639
  const updatedMetadata = {
13483
- ...requirements.metadata,
13640
+ ...requirements._metadata,
13484
13641
  templateMode: true,
13485
13642
  };
13486
13643
  // Add a general instruction about using structured templates
@@ -13490,21 +13647,21 @@ class TemplateCommitmentDefinition extends BaseCommitmentDefinition {
13490
13647
  `);
13491
13648
  return {
13492
13649
  ...this.appendToSystemMessage(requirements, templateModeInstruction, '\n\n'),
13493
- metadata: updatedMetadata,
13650
+ _metadata: updatedMetadata,
13494
13651
  };
13495
13652
  }
13496
13653
  // If content is provided, add the specific template instructions
13497
13654
  const templateSection = `Response Template: ${trimmedContent}`;
13498
13655
  // Store the template in metadata for potential programmatic access
13499
- const existingTemplates = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.templates) || [];
13656
+ const existingTemplates = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.templates) || [];
13500
13657
  const updatedMetadata = {
13501
- ...requirements.metadata,
13658
+ ...requirements._metadata,
13502
13659
  templates: [...existingTemplates, trimmedContent],
13503
13660
  templateMode: true,
13504
13661
  };
13505
13662
  return {
13506
13663
  ...this.appendToSystemMessage(requirements, templateSection, '\n\n'),
13507
- metadata: updatedMetadata,
13664
+ _metadata: updatedMetadata,
13508
13665
  };
13509
13666
  }
13510
13667
  }
@@ -13841,8 +13998,8 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
13841
13998
  return this.appendToSystemMessage({
13842
13999
  ...requirements,
13843
14000
  tools: updatedTools,
13844
- metadata: {
13845
- ...requirements.metadata,
14001
+ _metadata: {
14002
+ ...requirements._metadata,
13846
14003
  useBrowser: true,
13847
14004
  },
13848
14005
  }, spaceTrim$1(`
@@ -14071,8 +14228,8 @@ class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
14071
14228
  return this.appendToSystemMessage({
14072
14229
  ...requirements,
14073
14230
  tools: updatedTools,
14074
- metadata: {
14075
- ...requirements.metadata,
14231
+ _metadata: {
14232
+ ...requirements._metadata,
14076
14233
  useEmail: content || true,
14077
14234
  },
14078
14235
  }, spaceTrim$1((block) => `
@@ -14207,8 +14364,8 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
14207
14364
  return this.appendToSystemMessage({
14208
14365
  ...requirements,
14209
14366
  tools: updatedTools,
14210
- metadata: {
14211
- ...requirements.metadata,
14367
+ _metadata: {
14368
+ ...requirements._metadata,
14212
14369
  useImageGenerator: content || true,
14213
14370
  },
14214
14371
  }, spaceTrim$1(`
@@ -14499,8 +14656,8 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
14499
14656
  return this.appendToSystemMessage({
14500
14657
  ...requirements,
14501
14658
  tools: updatedTools,
14502
- metadata: {
14503
- ...requirements.metadata,
14659
+ _metadata: {
14660
+ ...requirements._metadata,
14504
14661
  useSearchEngine: content || true,
14505
14662
  },
14506
14663
  }, spaceTrim$1((block) => `
@@ -14648,8 +14805,8 @@ class UseTimeCommitmentDefinition extends BaseCommitmentDefinition {
14648
14805
  return this.appendToSystemMessage({
14649
14806
  ...requirements,
14650
14807
  tools: updatedTools,
14651
- metadata: {
14652
- ...requirements.metadata,
14808
+ _metadata: {
14809
+ ...requirements._metadata,
14653
14810
  },
14654
14811
  }, spaceTrim$1((block) => `
14655
14812
  Time and date context:
@@ -15277,8 +15434,8 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
15277
15434
  // Store the agent name in metadata so commitments can access it
15278
15435
  requirements = {
15279
15436
  ...requirements,
15280
- metadata: {
15281
- ...requirements.metadata,
15437
+ _metadata: {
15438
+ ...requirements._metadata,
15282
15439
  agentName: parseResult.agentName,
15283
15440
  },
15284
15441
  };
@@ -21307,6 +21464,66 @@ const OPENAI_MODELS = exportJson({
21307
21464
  },
21308
21465
  /**/
21309
21466
  /**/
21467
+ {
21468
+ modelVariant: 'CHAT',
21469
+ modelTitle: 'gpt-5.2-codex',
21470
+ modelName: 'gpt-5.2-codex',
21471
+ modelDescription: 'High-capability Codex variant tuned for agentic code generation with large contexts and reasoning effort controls. Ideal for long-horizon coding workflows and multi-step reasoning.',
21472
+ pricing: {
21473
+ prompt: pricing(`$1.75 / 1M tokens`),
21474
+ output: pricing(`$14.00 / 1M tokens`),
21475
+ },
21476
+ },
21477
+ /**/
21478
+ /**/
21479
+ {
21480
+ modelVariant: 'CHAT',
21481
+ modelTitle: 'gpt-5.1-codex-max',
21482
+ modelName: 'gpt-5.1-codex-max',
21483
+ modelDescription: 'Premium GPT-5.1 Codex flavor that mirrors gpt-5.1 in capability and pricing while adding Codex tooling optimizations.',
21484
+ pricing: {
21485
+ prompt: pricing(`$1.25 / 1M tokens`),
21486
+ output: pricing(`$10.00 / 1M tokens`),
21487
+ },
21488
+ },
21489
+ /**/
21490
+ /**/
21491
+ {
21492
+ modelVariant: 'CHAT',
21493
+ modelTitle: 'gpt-5.1-codex',
21494
+ modelName: 'gpt-5.1-codex',
21495
+ modelDescription: 'Core GPT-5.1 Codex model focused on agentic coding tasks with a balanced trade-off between reasoning and cost.',
21496
+ pricing: {
21497
+ prompt: pricing(`$1.25 / 1M tokens`),
21498
+ output: pricing(`$10.00 / 1M tokens`),
21499
+ },
21500
+ },
21501
+ /**/
21502
+ /**/
21503
+ {
21504
+ modelVariant: 'CHAT',
21505
+ modelTitle: 'gpt-5.1-codex-mini',
21506
+ modelName: 'gpt-5.1-codex-mini',
21507
+ modelDescription: 'Compact, cost-effective GPT-5.1 Codex variant with a smaller context window ideal for cheap assistant iterations that still require coding awareness.',
21508
+ pricing: {
21509
+ prompt: pricing(`$0.25 / 1M tokens`),
21510
+ output: pricing(`$2.00 / 1M tokens`),
21511
+ },
21512
+ },
21513
+ /**/
21514
+ /**/
21515
+ {
21516
+ modelVariant: 'CHAT',
21517
+ modelTitle: 'gpt-5-codex',
21518
+ modelName: 'gpt-5-codex',
21519
+ modelDescription: 'Legacy GPT-5 Codex model built for agentic coding workloads with the same pricing as GPT-5 and a focus on stability.',
21520
+ pricing: {
21521
+ prompt: pricing(`$1.25 / 1M tokens`),
21522
+ output: pricing(`$10.00 / 1M tokens`),
21523
+ },
21524
+ },
21525
+ /**/
21526
+ /**/
21310
21527
  {
21311
21528
  modelVariant: 'CHAT',
21312
21529
  modelTitle: 'gpt-5-mini',
@@ -22011,6 +22228,32 @@ function isUnsupportedParameterError(error) {
22011
22228
  errorMessage.includes('does not support'));
22012
22229
  }
22013
22230
 
22231
+ /**
22232
+ * Provides access to the structured clone implementation when available.
22233
+ */
22234
+ function getStructuredCloneFunction() {
22235
+ return globalThis.structuredClone;
22236
+ }
22237
+ /**
22238
+ * Checks whether the prompt is a chat prompt that carries file attachments.
22239
+ */
22240
+ function hasChatPromptFiles(prompt) {
22241
+ return 'files' in prompt && Array.isArray(prompt.files);
22242
+ }
22243
+ /**
22244
+ * Creates a deep copy of the prompt while keeping attached files intact when structured clone is not available.
22245
+ */
22246
+ function clonePromptPreservingFiles(prompt) {
22247
+ const structuredCloneFn = getStructuredCloneFunction();
22248
+ if (typeof structuredCloneFn === 'function') {
22249
+ return structuredCloneFn(prompt);
22250
+ }
22251
+ const clonedPrompt = JSON.parse(JSON.stringify(prompt));
22252
+ if (hasChatPromptFiles(prompt)) {
22253
+ clonedPrompt.files = prompt.files;
22254
+ }
22255
+ return clonedPrompt;
22256
+ }
22014
22257
  /**
22015
22258
  * Execution Tools for calling OpenAI API or other OpenAI compatible provider
22016
22259
  *
@@ -22095,7 +22338,7 @@ class OpenAiCompatibleExecutionTools {
22095
22338
  */
22096
22339
  async callChatModelStream(prompt, onProgress) {
22097
22340
  // Deep clone prompt and modelRequirements to avoid mutation across calls
22098
- const clonedPrompt = JSON.parse(JSON.stringify(prompt));
22341
+ const clonedPrompt = clonePromptPreservingFiles(prompt);
22099
22342
  // Use local Set for retried parameters to ensure independence and thread safety
22100
22343
  const retriedUnsupportedParameters = new Set();
22101
22344
  return this.callChatModelWithRetry(clonedPrompt, clonedPrompt.modelRequirements, [], retriedUnsupportedParameters, onProgress);
@@ -22122,7 +22365,10 @@ class OpenAiCompatibleExecutionTools {
22122
22365
  // <- TODO: [🈁] Use `seed` here AND/OR use is `isDeterministic` for entire execution tools
22123
22366
  // <- Note: [🧆]
22124
22367
  }; // <- TODO: [💩] Guard here types better
22125
- if (format === 'JSON') {
22368
+ if (currentModelRequirements.responseFormat !== undefined) {
22369
+ modelSettings.response_format = currentModelRequirements.responseFormat;
22370
+ }
22371
+ else if (format === 'JSON') {
22126
22372
  modelSettings.response_format = {
22127
22373
  type: 'json_object',
22128
22374
  };
@@ -23603,7 +23849,9 @@ class OpenAiVectorStoreHandler extends OpenAiExecutionTools {
23603
23849
  const processingStartedAtMs = Date.now();
23604
23850
  for (const [index, source] of knowledgeSources.entries()) {
23605
23851
  try {
23606
- const sourceType = source.startsWith('http') || source.startsWith('https') ? 'url' : 'file';
23852
+ const isDataUrl = isDataUrlKnowledgeSource(source);
23853
+ const isHttp = source.startsWith('http://') || source.startsWith('https://');
23854
+ const sourceType = isDataUrl ? 'data_url' : isHttp ? 'url' : 'file';
23607
23855
  if (this.options.isVerbose) {
23608
23856
  console.info('[🤰]', 'Processing knowledge source', {
23609
23857
  index: index + 1,
@@ -23613,8 +23861,27 @@ class OpenAiVectorStoreHandler extends OpenAiExecutionTools {
23613
23861
  logLabel,
23614
23862
  });
23615
23863
  }
23616
- // Check if it's a URL
23617
- if (source.startsWith('http://') || source.startsWith('https://')) {
23864
+ if (isDataUrl) {
23865
+ const parsed = parseDataUrlKnowledgeSource(source);
23866
+ if (!parsed) {
23867
+ skippedSources.push({ source, reason: 'invalid_data_url' });
23868
+ if (this.options.isVerbose) {
23869
+ console.info('[🤰]', 'Skipping knowledge source (invalid data URL)', {
23870
+ source,
23871
+ sourceType,
23872
+ logLabel,
23873
+ });
23874
+ }
23875
+ continue;
23876
+ }
23877
+ const dataUrlFile = new File([parsed.buffer], parsed.filename, {
23878
+ type: parsed.mimeType,
23879
+ });
23880
+ fileStreams.push(dataUrlFile);
23881
+ totalBytes += parsed.buffer.length;
23882
+ continue;
23883
+ }
23884
+ if (isHttp) {
23618
23885
  const downloadResult = await this.downloadKnowledgeSourceFile({
23619
23886
  source,
23620
23887
  timeoutMs: downloadTimeoutMs,
@@ -23716,6 +23983,64 @@ class OpenAiVectorStoreHandler extends OpenAiExecutionTools {
23716
23983
  }
23717
23984
 
23718
23985
  const DEFAULT_AGENT_KIT_MODEL_NAME = 'gpt-5.2';
23986
+ const DEFAULT_JSON_SCHEMA_NAME = 'StructuredOutput';
23987
+ /*
23988
+ TODO: Use or remove
23989
+ const EMPTY_JSON_SCHEMA: JsonSchemaDefinition['schema'] = {
23990
+ type: 'object',
23991
+ properties: {},
23992
+ required: [],
23993
+ additionalProperties: true,
23994
+ };
23995
+ */
23996
+ function buildJsonSchemaDefinition(jsonSchema) {
23997
+ var _a, _b, _c;
23998
+ const schema = (_a = jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.schema) !== null && _a !== void 0 ? _a : {};
23999
+ return {
24000
+ type: 'json_schema',
24001
+ name: (_b = jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.name) !== null && _b !== void 0 ? _b : DEFAULT_JSON_SCHEMA_NAME,
24002
+ strict: Boolean(jsonSchema === null || jsonSchema === void 0 ? void 0 : jsonSchema.strict),
24003
+ schema: {
24004
+ type: 'object',
24005
+ properties: ((_c = schema.properties) !== null && _c !== void 0 ? _c : {}),
24006
+ required: Array.isArray(schema.required) ? schema.required : [],
24007
+ additionalProperties: schema.additionalProperties === undefined ? true : Boolean(schema.additionalProperties),
24008
+ description: schema.description,
24009
+ },
24010
+ };
24011
+ }
24012
+ /**
24013
+ * Maps OpenAI `response_format` payloads to AgentKit output types so the runner can forward
24014
+ * structured-output preferences to OpenAI while still reusing the same AgentKit agent instance.
24015
+ *
24016
+ * @param responseFormat - The OpenAI `response_format` payload from the user request.
24017
+ * @returns An Agent output type compatible with the requested schema or `undefined` when no impact is required.
24018
+ * @private utility of Open AI
24019
+ */
24020
+ function mapResponseFormatToAgentOutputType(responseFormat) {
24021
+ if (!responseFormat) {
24022
+ return undefined;
24023
+ }
24024
+ if (typeof responseFormat === 'string') {
24025
+ if (responseFormat === 'text') {
24026
+ return 'text';
24027
+ }
24028
+ if (responseFormat === 'json_schema' || responseFormat === 'json_object') {
24029
+ return buildJsonSchemaDefinition();
24030
+ }
24031
+ return 'text';
24032
+ }
24033
+ switch (responseFormat.type) {
24034
+ case 'text':
24035
+ return 'text';
24036
+ case 'json_schema':
24037
+ return buildJsonSchemaDefinition(responseFormat.json_schema);
24038
+ case 'json_object':
24039
+ return buildJsonSchemaDefinition();
24040
+ default:
24041
+ return undefined;
24042
+ }
24043
+ }
23719
24044
  /**
23720
24045
  * Execution tools for OpenAI AgentKit (Agents SDK).
23721
24046
  *
@@ -23763,6 +24088,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
23763
24088
  ...parameters,
23764
24089
  modelName: this.agentKitModelName,
23765
24090
  });
24091
+ const responseFormatOutputType = mapResponseFormatToAgentOutputType(modelRequirements.responseFormat);
23766
24092
  const preparedAgentKitAgent = await this.prepareAgentKitAgent({
23767
24093
  name: (prompt.title || 'Agent'),
23768
24094
  instructions: modelRequirements.systemMessage || '',
@@ -23774,6 +24100,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
23774
24100
  prompt,
23775
24101
  rawPromptContent,
23776
24102
  onProgress,
24103
+ responseFormatOutputType,
23777
24104
  });
23778
24105
  }
23779
24106
  /**
@@ -23955,16 +24282,21 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
23955
24282
  ...prompt.parameters,
23956
24283
  modelName: this.agentKitModelName,
23957
24284
  });
24285
+ const agentForRun = options.responseFormatOutputType !== undefined
24286
+ ? openAiAgentKitAgent.clone({
24287
+ outputType: options.responseFormatOutputType,
24288
+ })
24289
+ : openAiAgentKitAgent;
23958
24290
  const start = $getCurrentDate();
23959
24291
  let latestContent = '';
23960
24292
  const toolCalls = [];
23961
24293
  const toolCallIndexById = new Map();
23962
24294
  const inputItems = await this.buildAgentKitInputItems(prompt, rawPromptContent);
23963
24295
  const rawRequest = {
23964
- agentName: openAiAgentKitAgent.name,
24296
+ agentName: agentForRun.name,
23965
24297
  input: inputItems,
23966
24298
  };
23967
- const streamResult = await run(openAiAgentKitAgent, inputItems, {
24299
+ const streamResult = await run(agentForRun, inputItems, {
23968
24300
  stream: true,
23969
24301
  context: { parameters: prompt.parameters },
23970
24302
  });
@@ -24953,22 +25285,28 @@ class AgentLlmExecutionTools {
24953
25285
  throw new Error('AgentLlmExecutionTools only supports chat prompts');
24954
25286
  }
24955
25287
  const modelRequirements = await this.getModelRequirements();
25288
+ const { _metadata, promptSuffix, ...sanitizedRequirements } = modelRequirements;
24956
25289
  const chatPrompt = prompt;
24957
25290
  let underlyingLlmResult;
24958
- // Create modified chat prompt with agent system message
25291
+ const chatPromptContentWithSuffix = promptSuffix
25292
+ ? `${chatPrompt.content}\n\n${promptSuffix}`
25293
+ : chatPrompt.content;
24959
25294
  const promptWithAgentModelRequirements = {
24960
25295
  ...chatPrompt,
25296
+ content: chatPromptContentWithSuffix,
24961
25297
  modelRequirements: {
24962
25298
  ...chatPrompt.modelRequirements,
24963
- ...modelRequirements,
25299
+ ...sanitizedRequirements,
24964
25300
  // Spread tools to convert readonly array to mutable
24965
- tools: modelRequirements.tools ? [...modelRequirements.tools] : chatPrompt.modelRequirements.tools,
25301
+ tools: sanitizedRequirements.tools
25302
+ ? [...sanitizedRequirements.tools]
25303
+ : chatPrompt.modelRequirements.tools,
24966
25304
  // Spread knowledgeSources to convert readonly array to mutable
24967
- knowledgeSources: modelRequirements.knowledgeSources
24968
- ? [...modelRequirements.knowledgeSources]
25305
+ knowledgeSources: sanitizedRequirements.knowledgeSources
25306
+ ? [...sanitizedRequirements.knowledgeSources]
24969
25307
  : undefined,
24970
25308
  // Prepend agent system message to existing system message
24971
- systemMessage: modelRequirements.systemMessage +
25309
+ systemMessage: sanitizedRequirements.systemMessage +
24972
25310
  (chatPrompt.modelRequirements.systemMessage
24973
25311
  ? `\n\n${chatPrompt.modelRequirements.systemMessage}`
24974
25312
  : ''),
@@ -24976,8 +25314,8 @@ class AgentLlmExecutionTools {
24976
25314
  };
24977
25315
  console.log('!!!! promptWithAgentModelRequirements:', promptWithAgentModelRequirements);
24978
25316
  if (OpenAiAgentKitExecutionTools.isOpenAiAgentKitExecutionTools(this.options.llmTools)) {
24979
- const requirementsHash = SHA256(JSON.stringify(modelRequirements)).toString();
24980
- const vectorStoreHash = SHA256(JSON.stringify((_a = modelRequirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])).toString();
25317
+ const requirementsHash = SHA256(JSON.stringify(sanitizedRequirements)).toString();
25318
+ const vectorStoreHash = SHA256(JSON.stringify((_a = sanitizedRequirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])).toString();
24981
25319
  const cachedVectorStore = AgentLlmExecutionTools.vectorStoreCache.get(this.title);
24982
25320
  const cachedAgentKit = AgentLlmExecutionTools.agentKitAgentCache.get(this.title);
24983
25321
  let preparedAgentKit = this.options.assistantPreparationMode === 'external'
@@ -25004,7 +25342,7 @@ class AgentLlmExecutionTools {
25004
25342
  agent: this.title,
25005
25343
  });
25006
25344
  }
25007
- if (!vectorStoreId && ((_b = modelRequirements.knowledgeSources) === null || _b === void 0 ? void 0 : _b.length)) {
25345
+ if (!vectorStoreId && ((_b = sanitizedRequirements.knowledgeSources) === null || _b === void 0 ? void 0 : _b.length)) {
25008
25346
  emitAssistantPreparationProgress({
25009
25347
  onProgress,
25010
25348
  prompt,
@@ -25020,9 +25358,9 @@ class AgentLlmExecutionTools {
25020
25358
  });
25021
25359
  preparedAgentKit = await this.options.llmTools.prepareAgentKitAgent({
25022
25360
  name: this.title,
25023
- instructions: modelRequirements.systemMessage || '',
25024
- knowledgeSources: modelRequirements.knowledgeSources,
25025
- tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
25361
+ instructions: sanitizedRequirements.systemMessage || '',
25362
+ knowledgeSources: sanitizedRequirements.knowledgeSources,
25363
+ tools: sanitizedRequirements.tools ? [...sanitizedRequirements.tools] : undefined,
25026
25364
  vectorStoreId,
25027
25365
  });
25028
25366
  }
@@ -25037,15 +25375,17 @@ class AgentLlmExecutionTools {
25037
25375
  requirementsHash,
25038
25376
  vectorStoreId: preparedAgentKit.vectorStoreId,
25039
25377
  });
25378
+ const responseFormatOutputType = mapResponseFormatToAgentOutputType(promptWithAgentModelRequirements.modelRequirements.responseFormat);
25040
25379
  underlyingLlmResult = await this.options.llmTools.callChatModelStreamWithPreparedAgent({
25041
25380
  openAiAgentKitAgent: preparedAgentKit.agent,
25042
25381
  prompt: promptWithAgentModelRequirements,
25043
25382
  onProgress,
25383
+ responseFormatOutputType,
25044
25384
  });
25045
25385
  }
25046
25386
  else if (OpenAiAssistantExecutionTools.isOpenAiAssistantExecutionTools(this.options.llmTools)) {
25047
25387
  // ... deprecated path ...
25048
- const requirementsHash = SHA256(JSON.stringify(modelRequirements)).toString();
25388
+ const requirementsHash = SHA256(JSON.stringify(sanitizedRequirements)).toString();
25049
25389
  const cached = AgentLlmExecutionTools.assistantCache.get(this.title);
25050
25390
  let assistant;
25051
25391
  if (this.options.assistantPreparationMode === 'external') {
@@ -25087,9 +25427,9 @@ class AgentLlmExecutionTools {
25087
25427
  assistant = await this.options.llmTools.updateAssistant({
25088
25428
  assistantId: cached.assistantId,
25089
25429
  name: this.title,
25090
- instructions: modelRequirements.systemMessage,
25091
- knowledgeSources: modelRequirements.knowledgeSources,
25092
- tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
25430
+ instructions: sanitizedRequirements.systemMessage,
25431
+ knowledgeSources: sanitizedRequirements.knowledgeSources,
25432
+ tools: sanitizedRequirements.tools ? [...sanitizedRequirements.tools] : undefined,
25093
25433
  });
25094
25434
  AgentLlmExecutionTools.assistantCache.set(this.title, {
25095
25435
  assistantId: assistant.assistantId,
@@ -25112,9 +25452,9 @@ class AgentLlmExecutionTools {
25112
25452
  });
25113
25453
  assistant = await this.options.llmTools.createNewAssistant({
25114
25454
  name: this.title,
25115
- instructions: modelRequirements.systemMessage,
25116
- knowledgeSources: modelRequirements.knowledgeSources,
25117
- tools: modelRequirements.tools ? [...modelRequirements.tools] : undefined,
25455
+ instructions: sanitizedRequirements.systemMessage,
25456
+ knowledgeSources: sanitizedRequirements.knowledgeSources,
25457
+ tools: sanitizedRequirements.tools ? [...sanitizedRequirements.tools] : undefined,
25118
25458
  /*
25119
25459
  !!!
25120
25460
  metadata: {
@@ -25156,13 +25496,19 @@ class AgentLlmExecutionTools {
25156
25496
  }
25157
25497
  }
25158
25498
  let content = underlyingLlmResult.content;
25159
- // Note: Cleanup the AI artifacts from the content
25160
- content = humanizeAiText(content);
25161
- // Note: Make sure the content is Promptbook-like
25162
- content = promptbookifyAiText(content);
25499
+ if (typeof content === 'string') {
25500
+ // Note: Cleanup the AI artifacts from the content
25501
+ content = humanizeAiText(content);
25502
+ // Note: Make sure the content is Promptbook-like
25503
+ content = promptbookifyAiText(content);
25504
+ }
25505
+ else {
25506
+ // TODO: Maybe deep `humanizeAiText` + `promptbookifyAiText` inside of the object
25507
+ content = JSON.stringify(content);
25508
+ }
25163
25509
  const agentResult = {
25164
25510
  ...underlyingLlmResult,
25165
- content,
25511
+ content: content,
25166
25512
  modelName: this.modelName,
25167
25513
  };
25168
25514
  return agentResult;
@@ -25351,7 +25697,6 @@ class Agent extends AgentLlmExecutionTools {
25351
25697
  * Note: This method also implements the learning mechanism
25352
25698
  */
25353
25699
  async callChatModelStream(prompt, onProgress) {
25354
- var _a;
25355
25700
  // [1] Check if the user is asking the same thing as in the samples
25356
25701
  const modelRequirements = await this.getModelRequirements();
25357
25702
  if (modelRequirements.samples) {
@@ -25399,7 +25744,7 @@ class Agent extends AgentLlmExecutionTools {
25399
25744
  if (result.rawResponse && 'sample' in result.rawResponse) {
25400
25745
  return result;
25401
25746
  }
25402
- if ((_a = modelRequirements.metadata) === null || _a === void 0 ? void 0 : _a.isClosed) {
25747
+ if (modelRequirements.isClosed) {
25403
25748
  return result;
25404
25749
  }
25405
25750
  // Note: [0] Notify start of self-learning
@@ -25684,6 +26029,40 @@ function book(strings, ...values) {
25684
26029
  * Note: [💞] Ignore a discrepancy between file name and entity name
25685
26030
  */
25686
26031
 
26032
+ /**
26033
+ * Builds a stable identity string for tool calls across partial updates.
26034
+ *
26035
+ * @param toolCall - Tool call entry to identify.
26036
+ * @returns Stable identity string for deduplication.
26037
+ *
26038
+ * @private function of <Chat/>
26039
+ */
26040
+ function getToolCallIdentity(toolCall) {
26041
+ const rawToolCall = toolCall.rawToolCall;
26042
+ const rawId = (rawToolCall === null || rawToolCall === void 0 ? void 0 : rawToolCall.id) || (rawToolCall === null || rawToolCall === void 0 ? void 0 : rawToolCall.callId) || (rawToolCall === null || rawToolCall === void 0 ? void 0 : rawToolCall.call_id);
26043
+ if (rawId) {
26044
+ return `id:${rawId}`;
26045
+ }
26046
+ if (toolCall.createdAt) {
26047
+ return `time:${toolCall.createdAt}:${toolCall.name}`;
26048
+ }
26049
+ const argsKey = (() => {
26050
+ if (typeof toolCall.arguments === 'string') {
26051
+ return toolCall.arguments;
26052
+ }
26053
+ if (!toolCall.arguments) {
26054
+ return '';
26055
+ }
26056
+ try {
26057
+ return JSON.stringify(toolCall.arguments);
26058
+ }
26059
+ catch (_a) {
26060
+ return '';
26061
+ }
26062
+ })();
26063
+ return `fallback:${toolCall.name}:${argsKey}`;
26064
+ }
26065
+
25687
26066
  /**
25688
26067
  * Resolve a remote META IMAGE value into an absolute URL when possible.
25689
26068
  */
@@ -25913,26 +26292,7 @@ class RemoteAgent extends Agent {
25913
26292
  };
25914
26293
  };
25915
26294
  const getToolCallKey = (toolCall) => {
25916
- var _a;
25917
- const rawId = (_a = toolCall.rawToolCall) === null || _a === void 0 ? void 0 : _a.id;
25918
- if (rawId) {
25919
- return `id:${rawId}`;
25920
- }
25921
- const argsKey = (() => {
25922
- if (typeof toolCall.arguments === 'string') {
25923
- return toolCall.arguments;
25924
- }
25925
- if (!toolCall.arguments) {
25926
- return '';
25927
- }
25928
- try {
25929
- return JSON.stringify(toolCall.arguments);
25930
- }
25931
- catch (_a) {
25932
- return '';
25933
- }
25934
- })();
25935
- return `${toolCall.name}:${toolCall.createdAt || ''}:${argsKey}`;
26295
+ return getToolCallIdentity(toolCall);
25936
26296
  };
25937
26297
  const mergeToolCall = (existing, incoming) => {
25938
26298
  const incomingResult = incoming.result;