@promptbook/browser 0.110.0 → 0.111.0-1

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 (33) hide show
  1. package/README.md +4 -0
  2. package/esm/index.es.js +677 -171
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/src/_packages/utils.index.d.ts +12 -0
  5. package/esm/typings/src/book-2.0/agent-source/BookEditable.d.ts +41 -0
  6. package/esm/typings/src/book-2.0/agent-source/CreateAgentModelRequirementsOptions.d.ts +5 -0
  7. package/esm/typings/src/book-components/Chat/Chat/ImagePromptRenderer.d.ts +21 -0
  8. package/esm/typings/src/book-components/Chat/LlmChat/LlmChatProps.d.ts +5 -0
  9. package/esm/typings/src/book-components/Chat/LlmChat/defaults.d.ts +9 -0
  10. package/esm/typings/src/book-components/Chat/hooks/useChatActionsOverlap.d.ts +6 -0
  11. package/esm/typings/src/book-components/Chat/save/_common/ChatSaveFormatDefinition.d.ts +7 -1
  12. package/esm/typings/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +6 -5
  13. package/esm/typings/src/book-components/Chat/save/index.d.ts +3 -3
  14. package/esm/typings/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +11 -0
  15. package/esm/typings/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +2 -2
  16. package/esm/typings/src/book-components/Chat/utils/parseImagePrompts.d.ts +42 -0
  17. package/esm/typings/src/book-components/Chat/utils/parseImagePrompts.test.d.ts +1 -0
  18. package/esm/typings/src/commitments/MEMORY/MEMORY.d.ts +67 -0
  19. package/esm/typings/src/commitments/MEMORY/MEMORY.test.d.ts +1 -0
  20. package/esm/typings/src/commitments/USE_IMAGE_GENERATOR/USE_IMAGE_GENERATOR.d.ts +3 -12
  21. package/esm/typings/src/commitments/_common/toolRuntimeContext.d.ts +49 -0
  22. package/esm/typings/src/constants/streaming.d.ts +20 -0
  23. package/esm/typings/src/llm-providers/openai/utils/buildToolInvocationScript.d.ts +9 -0
  24. package/esm/typings/src/utils/clientVersion.d.ts +51 -0
  25. package/esm/typings/src/utils/knowledge/inlineKnowledgeSource.d.ts +13 -9
  26. package/esm/typings/src/utils/knowledge/simplifyKnowledgeLabel.d.ts +20 -0
  27. package/esm/typings/src/utils/knowledge/simplifyKnowledgeLabel.test.d.ts +1 -0
  28. package/esm/typings/src/utils/normalization/constructImageFilename.d.ts +18 -0
  29. package/esm/typings/src/utils/normalization/constructImageFilename.test.d.ts +1 -0
  30. package/esm/typings/src/version.d.ts +1 -1
  31. package/package.json +2 -2
  32. package/umd/index.umd.js +677 -171
  33. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -29,7 +29,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
29
29
  * @generated
30
30
  * @see https://github.com/webgptorg/promptbook
31
31
  */
32
- const PROMPTBOOK_ENGINE_VERSION = '0.110.0';
32
+ const PROMPTBOOK_ENGINE_VERSION = '0.111.0-1';
33
33
  /**
34
34
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
35
35
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -3860,6 +3860,36 @@ function prompt(strings, ...values) {
3860
3860
  * Note: [💞] Ignore a discrepancy between file name and entity name
3861
3861
  */
3862
3862
 
3863
+ /**
3864
+ * HTTP header used by Promptbook clients to advertise their release version.
3865
+ *
3866
+ * @public exported from `@promptbook/utils`
3867
+ */
3868
+ const CLIENT_VERSION_HEADER = 'x-promptbook-client-version';
3869
+ /**
3870
+ * The latest client (engine) version that the server expects.
3871
+ *
3872
+ * @public exported from `@promptbook/utils`
3873
+ */
3874
+ const CLIENT_LATEST_VERSION = PROMPTBOOK_ENGINE_VERSION;
3875
+ /**
3876
+ * Creates a headers object that includes the client version header.
3877
+ *
3878
+ * @param headers - Optional base headers to clone.
3879
+ * @returns New headers object augmented with `CLIENT_VERSION_HEADER`.
3880
+ *
3881
+ * @public exported from `@promptbook/utils`
3882
+ */
3883
+ function attachClientVersionHeader(headers) {
3884
+ return {
3885
+ ...(headers !== null && headers !== void 0 ? headers : {}),
3886
+ [CLIENT_VERSION_HEADER]: CLIENT_LATEST_VERSION,
3887
+ };
3888
+ }
3889
+ /**
3890
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3891
+ */
3892
+
3863
3893
  /**
3864
3894
  * Detects if the code is running in a browser environment in main thread (Not in a web worker)
3865
3895
  *
@@ -6198,28 +6228,14 @@ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
6198
6228
  * Note: [💞] Ignore a discrepancy between file name and entity name
6199
6229
  */
6200
6230
 
6201
- /**
6202
- * @@@
6203
- *
6204
- * @private thing of inline knowledge
6205
- */
6231
+ /** @private The default base name for inline knowledge files when the content lacks identifying text */
6206
6232
  const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';
6207
- /**
6208
- * @@@
6209
- *
6210
- * @private thing of inline knowledge
6211
- */
6233
+ /** @private The default file extension used for inline knowledge uploads */
6212
6234
  const INLINE_KNOWLEDGE_EXTENSION = '.txt';
6213
- /**
6214
- * @@@
6215
- *
6216
- * @private thing of inline knowledge
6217
- */
6235
+ /** @private Prefix that identifies base64 data URLs */
6218
6236
  const DATA_URL_PREFIX = 'data:';
6219
6237
  /**
6220
- * @@@
6221
- *
6222
- * @private thing of inline knowledge
6238
+ * @private Retrieves the first meaningful line from the inline content.
6223
6239
  */
6224
6240
  function getFirstNonEmptyLine(content) {
6225
6241
  const lines = content.split(/\r?\n/);
@@ -6232,9 +6248,7 @@ function getFirstNonEmptyLine(content) {
6232
6248
  return null;
6233
6249
  }
6234
6250
  /**
6235
- * @@@
6236
- *
6237
- * @private thing of inline knowledge
6251
+ * @private Determines the base file name by normalizing the first non-empty line.
6238
6252
  */
6239
6253
  function deriveBaseFilename(content) {
6240
6254
  const firstLine = getFirstNonEmptyLine(content);
@@ -6245,22 +6259,18 @@ function deriveBaseFilename(content) {
6245
6259
  return normalized || INLINE_KNOWLEDGE_BASE_NAME;
6246
6260
  }
6247
6261
  /**
6248
- * Creates a data URL that represents the inline knowledge content as a text file.
6249
- *
6250
- * @private thing of inline knowledge
6262
+ * @private Converts inline knowledge into the internal metadata form used for uploads.
6251
6263
  */
6252
6264
  function createInlineKnowledgeSourceFile(content) {
6253
6265
  const trimmedContent = content.trim();
6254
6266
  const baseName = deriveBaseFilename(trimmedContent);
6255
6267
  const filename = `${baseName}${INLINE_KNOWLEDGE_EXTENSION}`;
6256
6268
  const mimeType = 'text/plain';
6257
- const base64 = Buffer.from(trimmedContent, 'utf-8').toString('base64');
6258
- const encodedFilename = encodeURIComponent(filename);
6259
- const url = `${DATA_URL_PREFIX}${mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
6269
+ const buffer = Buffer.from(trimmedContent, 'utf-8');
6260
6270
  return {
6261
6271
  filename,
6262
6272
  mimeType,
6263
- url,
6273
+ buffer,
6264
6274
  };
6265
6275
  }
6266
6276
  /**
@@ -6271,10 +6281,18 @@ function createInlineKnowledgeSourceFile(content) {
6271
6281
  function isDataUrlKnowledgeSource(source) {
6272
6282
  return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);
6273
6283
  }
6284
+ /**
6285
+ * @private Converts a stored inline knowledge file into a data URL for backwards compatibility.
6286
+ */
6287
+ function inlineKnowledgeSourceToDataUrl(source) {
6288
+ const base64 = source.buffer.toString('base64');
6289
+ const encodedFilename = encodeURIComponent(source.filename);
6290
+ return `${DATA_URL_PREFIX}${source.mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
6291
+ }
6274
6292
  /**
6275
6293
  * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.
6276
6294
  *
6277
- * @private thing of inline knowledge
6295
+ * @private utility of inline knowledge processing
6278
6296
  */
6279
6297
  function parseDataUrlKnowledgeSource(source) {
6280
6298
  if (!isDataUrlKnowledgeSource(source)) {
@@ -6407,6 +6425,7 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
6407
6425
  `);
6408
6426
  }
6409
6427
  applyToAgentModelRequirements(requirements, content) {
6428
+ var _a;
6410
6429
  const trimmedContent = content.trim();
6411
6430
  if (!trimmedContent) {
6412
6431
  return requirements;
@@ -6427,9 +6446,13 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
6427
6446
  }
6428
6447
  else {
6429
6448
  const inlineSource = createInlineKnowledgeSourceFile(trimmedContent);
6449
+ const existingInlineSources = (((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.inlineKnowledgeSources) || []).slice();
6430
6450
  const updatedRequirements = {
6431
6451
  ...requirements,
6432
- knowledgeSources: [...(requirements.knowledgeSources || []), inlineSource.url],
6452
+ _metadata: {
6453
+ ...requirements._metadata,
6454
+ inlineKnowledgeSources: [...existingInlineSources, inlineSource],
6455
+ },
6433
6456
  };
6434
6457
  const knowledgeInfo = `Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`;
6435
6458
  return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
@@ -6511,6 +6534,237 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
6511
6534
  * Note: [💞] Ignore a discrepancy between file name and entity name
6512
6535
  */
6513
6536
 
6537
+ /**
6538
+ * @@@
6539
+ *
6540
+ * @private utility for commitments
6541
+ */
6542
+ function formatOptionalInstructionBlock(label, content) {
6543
+ const trimmedContent = spaceTrim$1(content);
6544
+ if (!trimmedContent) {
6545
+ return '';
6546
+ }
6547
+ return spaceTrim$1((block) => `
6548
+ - ${label}:
6549
+ ${block(trimmedContent
6550
+ .split(/\r?\n/)
6551
+ .map((line) => `- ${line}`)
6552
+ .join('\n'))}
6553
+ `);
6554
+ }
6555
+
6556
+ /**
6557
+ * Prompt parameter key used to pass hidden runtime context to tool execution.
6558
+ *
6559
+ * @private internal runtime wiring for commitment tools
6560
+ */
6561
+ const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
6562
+ /**
6563
+ * Hidden argument key used to pass runtime context into individual tool calls.
6564
+ *
6565
+ * @private internal runtime wiring for commitment tools
6566
+ */
6567
+ const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
6568
+ /**
6569
+ * Parses unknown runtime context payload into a normalized object.
6570
+ *
6571
+ * @private internal runtime wiring for commitment tools
6572
+ */
6573
+ function parseToolRuntimeContext(rawValue) {
6574
+ if (!rawValue) {
6575
+ return null;
6576
+ }
6577
+ let parsed = rawValue;
6578
+ if (typeof rawValue === 'string') {
6579
+ try {
6580
+ parsed = JSON.parse(rawValue);
6581
+ }
6582
+ catch (_a) {
6583
+ return null;
6584
+ }
6585
+ }
6586
+ if (!parsed || typeof parsed !== 'object') {
6587
+ return null;
6588
+ }
6589
+ return parsed;
6590
+ }
6591
+ /**
6592
+ * Reads runtime context attached to tool call arguments.
6593
+ *
6594
+ * @private internal runtime wiring for commitment tools
6595
+ */
6596
+ function readToolRuntimeContextFromToolArgs(args) {
6597
+ return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
6598
+ }
6599
+ /**
6600
+ * Serializes runtime context for prompt parameters.
6601
+ *
6602
+ * @private internal runtime wiring for commitment tools
6603
+ */
6604
+ function serializeToolRuntimeContext(context) {
6605
+ return JSON.stringify(context);
6606
+ }
6607
+ /**
6608
+ * Note: [💞] Ignore a discrepancy between file name and entity name
6609
+ */
6610
+
6611
+ /**
6612
+ * Tool name used to retrieve persisted user memory.
6613
+ *
6614
+ * @private internal MEMORY commitment constant
6615
+ */
6616
+ const RETRIEVE_USER_MEMORY_TOOL_NAME = 'retrieve_user_memory';
6617
+ /**
6618
+ * Tool name used to store persisted user memory.
6619
+ *
6620
+ * @private internal MEMORY commitment constant
6621
+ */
6622
+ const STORE_USER_MEMORY_TOOL_NAME = 'store_user_memory';
6623
+ const UPDATE_USER_MEMORY_TOOL_NAME = 'update_user_memory';
6624
+ const DELETE_USER_MEMORY_TOOL_NAME = 'delete_user_memory';
6625
+ /**
6626
+ * Resolves runtime context from hidden tool arguments.
6627
+ *
6628
+ * @private utility of MEMORY commitment
6629
+ */
6630
+ function resolveMemoryRuntimeContext(args) {
6631
+ const runtimeContext = readToolRuntimeContextFromToolArgs(args);
6632
+ const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
6633
+ return {
6634
+ enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
6635
+ userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
6636
+ username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
6637
+ agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
6638
+ agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
6639
+ isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
6640
+ };
6641
+ }
6642
+ /**
6643
+ * Builds a disabled memory-tool response payload.
6644
+ *
6645
+ * @private utility of MEMORY commitment
6646
+ */
6647
+ function createDisabledMemoryResult(action, message) {
6648
+ if (action === 'retrieve') {
6649
+ return {
6650
+ action,
6651
+ status: 'disabled',
6652
+ memories: [],
6653
+ message,
6654
+ };
6655
+ }
6656
+ if (action === 'store') {
6657
+ return {
6658
+ action,
6659
+ status: 'disabled',
6660
+ message,
6661
+ };
6662
+ }
6663
+ if (action === 'update') {
6664
+ return {
6665
+ action,
6666
+ status: 'disabled',
6667
+ message,
6668
+ };
6669
+ }
6670
+ if (action === 'delete') {
6671
+ return {
6672
+ action,
6673
+ status: 'disabled',
6674
+ message,
6675
+ };
6676
+ }
6677
+ throw new Error(`Unsupported memory tool action: ${action}`);
6678
+ }
6679
+ /**
6680
+ * Gets the runtime adapter and returns a disabled result when unavailable.
6681
+ *
6682
+ * @private utility of MEMORY commitment
6683
+ */
6684
+ function getRuntimeAdapterOrDisabledResult(action, runtimeContext) {
6685
+ if (!runtimeContext.enabled || runtimeContext.isTeamConversation) {
6686
+ return {
6687
+ adapter: null,
6688
+ disabledResult: createDisabledMemoryResult(action, runtimeContext.isTeamConversation
6689
+ ? 'Memory is disabled for TEAM conversations.'
6690
+ : 'Memory is disabled for unauthenticated users.'),
6691
+ };
6692
+ }
6693
+ {
6694
+ return {
6695
+ adapter: null,
6696
+ disabledResult: createDisabledMemoryResult(action, 'Memory runtime is not available in this environment.'),
6697
+ };
6698
+ }
6699
+ }
6700
+ /**
6701
+ * Parses retrieve memory arguments.
6702
+ *
6703
+ * @private utility of MEMORY commitment
6704
+ */
6705
+ function parseRetrieveMemoryArgs(args) {
6706
+ const query = typeof args.query === 'string' ? args.query.trim() : undefined;
6707
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
6708
+ return {
6709
+ query: query && query.length > 0 ? query : undefined,
6710
+ limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
6711
+ };
6712
+ }
6713
+ /**
6714
+ * Parses store memory arguments.
6715
+ *
6716
+ * @private utility of MEMORY commitment
6717
+ */
6718
+ function parseStoreMemoryArgs(args) {
6719
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
6720
+ if (!content) {
6721
+ throw new Error('Memory content is required.');
6722
+ }
6723
+ return {
6724
+ content,
6725
+ isGlobal: args.isGlobal === true,
6726
+ };
6727
+ }
6728
+ /**
6729
+ * Parses a memory identifier argument shared across MEMORY tools.
6730
+ *
6731
+ * @private utility of MEMORY commitment
6732
+ */
6733
+ function parseMemoryIdArg(value) {
6734
+ const memoryId = typeof value === 'string' ? value.trim() : '';
6735
+ if (!memoryId) {
6736
+ throw new Error('Memory id is required.');
6737
+ }
6738
+ return memoryId;
6739
+ }
6740
+ /**
6741
+ * Parses update memory arguments.
6742
+ *
6743
+ * @private utility of MEMORY commitment
6744
+ */
6745
+ function parseUpdateMemoryArgs(args) {
6746
+ const memoryId = parseMemoryIdArg(args.memoryId);
6747
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
6748
+ if (!content) {
6749
+ throw new Error('Memory content is required.');
6750
+ }
6751
+ const isGlobal = typeof args.isGlobal === 'boolean' ? args.isGlobal : undefined;
6752
+ return {
6753
+ memoryId,
6754
+ content,
6755
+ isGlobal,
6756
+ };
6757
+ }
6758
+ /**
6759
+ * Parses delete memory arguments.
6760
+ *
6761
+ * @private utility of MEMORY commitment
6762
+ */
6763
+ function parseDeleteMemoryArgs(args) {
6764
+ return {
6765
+ memoryId: parseMemoryIdArg(args.memoryId),
6766
+ };
6767
+ }
6514
6768
  /**
6515
6769
  * MEMORY commitment definition
6516
6770
  *
@@ -6532,6 +6786,9 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
6532
6786
  constructor(type = 'MEMORY') {
6533
6787
  super(type);
6534
6788
  }
6789
+ get requiresContent() {
6790
+ return false;
6791
+ }
6535
6792
  /**
6536
6793
  * Short one-line description of MEMORY.
6537
6794
  */
@@ -6551,21 +6808,14 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
6551
6808
  return spaceTrim$1(`
6552
6809
  # ${this.type}
6553
6810
 
6554
- Similar to KNOWLEDGE but focuses on remembering past interactions and user preferences. This commitment helps the agent maintain context about the user's history, preferences, and previous conversations.
6811
+ Enables persistent user memory for the current agent. The memory is stored by the runtime and can be retrieved in future conversations.
6555
6812
 
6556
6813
  ## Key aspects
6557
6814
 
6558
- - Both terms work identically and can be used interchangeably.
6559
- - Focuses on user-specific information and interaction history.
6560
- - Helps personalize responses based on past interactions.
6561
- - Maintains continuity across conversations.
6562
-
6563
- ## Differences from KNOWLEDGE
6564
-
6565
- - \`KNOWLEDGE\` is for domain expertise and factual information
6566
- - \`MEMORY\` is for user-specific context and preferences
6567
- - \`MEMORY\` creates more personalized interactions
6568
- - \`MEMORY\` often includes temporal or preference-based information
6815
+ - Both \`MEMORY\` and \`MEMORIES\` work identically.
6816
+ - Stores user-specific details through runtime tools.
6817
+ - Retrieves relevant memories for personalized responses.
6818
+ - Supports optional extra instructions in the commitment content.
6569
6819
 
6570
6820
  ## Examples
6571
6821
 
@@ -6573,10 +6823,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
6573
6823
  Personal Assistant
6574
6824
 
6575
6825
  PERSONA You are a personal productivity assistant
6576
- MEMORY User is a software developer working in JavaScript/React
6577
- MEMORY User prefers morning work sessions and afternoon meetings
6578
- MEMORY Previously helped with project planning for mobile apps
6579
- MEMORY User timezone: UTC-8 (Pacific Time)
6826
+ MEMORY Remember user projects and long-term preferences.
6580
6827
  GOAL Help optimize daily productivity and workflow
6581
6828
  \`\`\`
6582
6829
 
@@ -6584,10 +6831,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
6584
6831
  Learning Companion
6585
6832
 
6586
6833
  PERSONA You are an educational companion for programming students
6587
- MEMORY Student is learning Python as their first programming language
6588
- MEMORY Previous topics covered: variables, loops, functions
6589
- MEMORY Student learns best with practical examples and exercises
6590
- MEMORY Last session: working on list comprehensions
6834
+ MEMORY Remember only the student's learning progress and preferred study style.
6591
6835
  GOAL Provide progressive learning experiences tailored to student's pace
6592
6836
  \`\`\`
6593
6837
 
@@ -6595,23 +6839,245 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
6595
6839
  Customer Support Agent
6596
6840
 
6597
6841
  PERSONA You are a customer support representative
6598
- MEMORY Customer has premium subscription since 2023
6599
- MEMORY Previous issue: billing question resolved last month
6600
- MEMORY Customer prefers email communication over phone calls
6601
- MEMORY Account shows frequent use of advanced features
6842
+ MEMORY Remember only important support history and communication preferences.
6602
6843
  GOAL Provide personalized support based on customer history
6603
6844
  \`\`\`
6604
6845
  `);
6605
6846
  }
6606
6847
  applyToAgentModelRequirements(requirements, content) {
6607
- const trimmedContent = content.trim();
6608
- if (!trimmedContent) {
6609
- return requirements;
6848
+ const extraInstructions = formatOptionalInstructionBlock('Memory instructions', content);
6849
+ const existingTools = requirements.tools || [];
6850
+ const tools = [...existingTools];
6851
+ if (!tools.some((tool) => tool.name === RETRIEVE_USER_MEMORY_TOOL_NAME)) {
6852
+ tools.push({
6853
+ name: RETRIEVE_USER_MEMORY_TOOL_NAME,
6854
+ description: spaceTrim$1(`
6855
+ Retrieve previously stored user memories relevant to the current conversation.
6856
+ Use this before responding when user context can improve the answer.
6857
+ `),
6858
+ parameters: {
6859
+ type: 'object',
6860
+ properties: {
6861
+ query: {
6862
+ type: 'string',
6863
+ description: 'Optional query used to filter relevant memories.',
6864
+ },
6865
+ limit: {
6866
+ type: 'integer',
6867
+ description: 'Optional maximum number of memories to return (default 5, max 20).',
6868
+ },
6869
+ },
6870
+ },
6871
+ });
6872
+ }
6873
+ if (!tools.some((tool) => tool.name === STORE_USER_MEMORY_TOOL_NAME)) {
6874
+ tools.push({
6875
+ name: STORE_USER_MEMORY_TOOL_NAME,
6876
+ description: spaceTrim$1(`
6877
+ Store a durable user memory that should be remembered in future conversations.
6878
+ Store only stable and useful user-specific facts or preferences.
6879
+ `),
6880
+ parameters: {
6881
+ type: 'object',
6882
+ properties: {
6883
+ content: {
6884
+ type: 'string',
6885
+ description: 'Memory text to store.',
6886
+ },
6887
+ isGlobal: {
6888
+ type: 'boolean',
6889
+ description: 'Set true to make this memory global across all user agents.',
6890
+ },
6891
+ },
6892
+ required: ['content'],
6893
+ },
6894
+ });
6895
+ }
6896
+ if (!tools.some((tool) => tool.name === UPDATE_USER_MEMORY_TOOL_NAME)) {
6897
+ tools.push({
6898
+ name: UPDATE_USER_MEMORY_TOOL_NAME,
6899
+ description: spaceTrim$1(`
6900
+ Update an existing user memory after retrieving it, so the stored fact stays accurate.
6901
+ Always pass the memory id you retrieved along with the new content.
6902
+ `),
6903
+ parameters: {
6904
+ type: 'object',
6905
+ properties: {
6906
+ memoryId: {
6907
+ type: 'string',
6908
+ description: 'Unique identifier of the memory entry to update.',
6909
+ },
6910
+ content: {
6911
+ type: 'string',
6912
+ description: 'Updated memory text.',
6913
+ },
6914
+ isGlobal: {
6915
+ type: 'boolean',
6916
+ description: 'Set true to keep the fact global; omit or false to keep it agent-scoped.',
6917
+ },
6918
+ },
6919
+ required: ['memoryId', 'content'],
6920
+ },
6921
+ });
6922
+ }
6923
+ if (!tools.some((tool) => tool.name === DELETE_USER_MEMORY_TOOL_NAME)) {
6924
+ tools.push({
6925
+ name: DELETE_USER_MEMORY_TOOL_NAME,
6926
+ description: spaceTrim$1(`
6927
+ Delete a user memory that is no longer relevant. Deletions are soft so the record is hidden from future queries.
6928
+ `),
6929
+ parameters: {
6930
+ type: 'object',
6931
+ properties: {
6932
+ memoryId: {
6933
+ type: 'string',
6934
+ description: 'Unique identifier of the memory entry to delete.',
6935
+ },
6936
+ },
6937
+ required: ['memoryId'],
6938
+ },
6939
+ });
6610
6940
  }
6611
- // Create memory section for system message
6612
- const memorySection = `Memory: ${trimmedContent}`;
6613
- // Memory information is contextual and should be included in the system message
6614
- return this.appendToSystemMessage(requirements, memorySection, '\n\n');
6941
+ return this.appendToSystemMessage({
6942
+ ...requirements,
6943
+ tools,
6944
+ _metadata: {
6945
+ ...requirements._metadata,
6946
+ useMemory: content || true,
6947
+ },
6948
+ }, spaceTrim$1((block) => `
6949
+ Memory:
6950
+ - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
6951
+ - You can use persistent user memory tools.
6952
+ - Use "${RETRIEVE_USER_MEMORY_TOOL_NAME}" to load relevant memory before answering.
6953
+ - Use "${STORE_USER_MEMORY_TOOL_NAME}" to save stable user-specific facts that improve future help.
6954
+ - Use "${UPDATE_USER_MEMORY_TOOL_NAME}" to refresh an existing memory when the content changes.
6955
+ - Use "${DELETE_USER_MEMORY_TOOL_NAME}" to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
6956
+ - Store concise memory items and avoid duplicates.
6957
+ - Never claim memory was saved or loaded unless the tool confirms it.
6958
+ ${block(extraInstructions)}
6959
+ `));
6960
+ }
6961
+ /**
6962
+ * Gets human-readable titles for MEMORY tool functions.
6963
+ */
6964
+ getToolTitles() {
6965
+ return {
6966
+ [RETRIEVE_USER_MEMORY_TOOL_NAME]: 'User memory',
6967
+ [STORE_USER_MEMORY_TOOL_NAME]: 'Store user memory',
6968
+ [UPDATE_USER_MEMORY_TOOL_NAME]: 'Update user memory',
6969
+ [DELETE_USER_MEMORY_TOOL_NAME]: 'Delete user memory',
6970
+ };
6971
+ }
6972
+ /**
6973
+ * Gets MEMORY tool function implementations.
6974
+ */
6975
+ getToolFunctions() {
6976
+ return {
6977
+ async [RETRIEVE_USER_MEMORY_TOOL_NAME](args) {
6978
+ const runtimeContext = resolveMemoryRuntimeContext(args);
6979
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
6980
+ if (!adapter || disabledResult) {
6981
+ return JSON.stringify(disabledResult);
6982
+ }
6983
+ const parsedArgs = parseRetrieveMemoryArgs(args);
6984
+ try {
6985
+ const memories = await adapter.retrieveMemories(parsedArgs, runtimeContext);
6986
+ const result = {
6987
+ action: 'retrieve',
6988
+ status: 'ok',
6989
+ query: parsedArgs.query,
6990
+ memories,
6991
+ };
6992
+ return JSON.stringify(result);
6993
+ }
6994
+ catch (error) {
6995
+ const result = {
6996
+ action: 'retrieve',
6997
+ status: 'error',
6998
+ query: parsedArgs.query,
6999
+ memories: [],
7000
+ message: error instanceof Error ? error.message : String(error),
7001
+ };
7002
+ return JSON.stringify(result);
7003
+ }
7004
+ },
7005
+ async [STORE_USER_MEMORY_TOOL_NAME](args) {
7006
+ const runtimeContext = resolveMemoryRuntimeContext(args);
7007
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('store', runtimeContext);
7008
+ if (!adapter || disabledResult) {
7009
+ return JSON.stringify(disabledResult);
7010
+ }
7011
+ try {
7012
+ const parsedArgs = parseStoreMemoryArgs(args);
7013
+ const memory = await adapter.storeMemory(parsedArgs, runtimeContext);
7014
+ const result = {
7015
+ action: 'store',
7016
+ status: 'stored',
7017
+ memory,
7018
+ };
7019
+ return JSON.stringify(result);
7020
+ }
7021
+ catch (error) {
7022
+ const result = {
7023
+ action: 'store',
7024
+ status: 'error',
7025
+ message: error instanceof Error ? error.message : String(error),
7026
+ };
7027
+ return JSON.stringify(result);
7028
+ }
7029
+ },
7030
+ async [UPDATE_USER_MEMORY_TOOL_NAME](args) {
7031
+ const runtimeContext = resolveMemoryRuntimeContext(args);
7032
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('update', runtimeContext);
7033
+ if (!adapter || disabledResult) {
7034
+ return JSON.stringify(disabledResult);
7035
+ }
7036
+ try {
7037
+ const parsedArgs = parseUpdateMemoryArgs(args);
7038
+ const memory = await adapter.updateMemory(parsedArgs, runtimeContext);
7039
+ const result = {
7040
+ action: 'update',
7041
+ status: 'updated',
7042
+ memory,
7043
+ };
7044
+ return JSON.stringify(result);
7045
+ }
7046
+ catch (error) {
7047
+ const result = {
7048
+ action: 'update',
7049
+ status: 'error',
7050
+ message: error instanceof Error ? error.message : String(error),
7051
+ };
7052
+ return JSON.stringify(result);
7053
+ }
7054
+ },
7055
+ async [DELETE_USER_MEMORY_TOOL_NAME](args) {
7056
+ const runtimeContext = resolveMemoryRuntimeContext(args);
7057
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('delete', runtimeContext);
7058
+ if (!adapter || disabledResult) {
7059
+ return JSON.stringify(disabledResult);
7060
+ }
7061
+ try {
7062
+ const parsedArgs = parseDeleteMemoryArgs(args);
7063
+ const deleted = await adapter.deleteMemory(parsedArgs, runtimeContext);
7064
+ const result = {
7065
+ action: 'delete',
7066
+ status: 'deleted',
7067
+ memoryId: deleted.id,
7068
+ };
7069
+ return JSON.stringify(result);
7070
+ }
7071
+ catch (error) {
7072
+ const result = {
7073
+ action: 'delete',
7074
+ status: 'error',
7075
+ message: error instanceof Error ? error.message : String(error),
7076
+ };
7077
+ return JSON.stringify(result);
7078
+ }
7079
+ },
7080
+ };
6615
7081
  }
6616
7082
  }
6617
7083
  /**
@@ -8724,14 +9190,30 @@ function buildTeammateRequest(message, context) {
8724
9190
  /**
8725
9191
  * Builds a minimal chat prompt for teammate calls.
8726
9192
  */
8727
- function buildTeammatePrompt(request) {
9193
+ function buildTeammatePrompt(request, runtimeContext) {
8728
9194
  return {
8729
9195
  title: 'Teammate consultation',
8730
9196
  modelRequirements: {
8731
9197
  modelVariant: 'CHAT',
8732
9198
  },
8733
9199
  content: request,
8734
- parameters: {},
9200
+ parameters: {
9201
+ [TOOL_RUNTIME_CONTEXT_PARAMETER]: serializeToolRuntimeContext(runtimeContext),
9202
+ },
9203
+ };
9204
+ }
9205
+ /**
9206
+ * Creates teammate runtime context and marks conversation as team-only memory-disabled.
9207
+ */
9208
+ function createTeamConversationRuntimeContext(value) {
9209
+ const runtimeContext = parseToolRuntimeContext(value) || {};
9210
+ return {
9211
+ ...runtimeContext,
9212
+ memory: {
9213
+ ...(runtimeContext.memory || {}),
9214
+ enabled: false,
9215
+ isTeamConversation: true,
9216
+ },
8735
9217
  };
8736
9218
  }
8737
9219
  /**
@@ -8775,7 +9257,7 @@ function createTeamToolFunction(entry) {
8775
9257
  let toolCalls;
8776
9258
  try {
8777
9259
  const remoteAgent = await getRemoteTeammateAgent(entry.teammate.url);
8778
- const prompt = buildTeammatePrompt(request);
9260
+ const prompt = buildTeammatePrompt(request, createTeamConversationRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]));
8779
9261
  const teammateResult = await remoteAgent.callChatModel(prompt);
8780
9262
  response = teammateResult.content || '';
8781
9263
  toolCalls =
@@ -9325,25 +9807,6 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
9325
9807
  * Note: [💞] Ignore a discrepancy between file name and entity name
9326
9808
  */
9327
9809
 
9328
- /**
9329
- * @@@
9330
- *
9331
- * @private utility for commitments
9332
- */
9333
- function formatOptionalInstructionBlock(label, content) {
9334
- const trimmedContent = spaceTrim$1(content);
9335
- if (!trimmedContent) {
9336
- return '';
9337
- }
9338
- return spaceTrim$1((block) => `
9339
- - ${label}:
9340
- ${block(trimmedContent
9341
- .split(/\r?\n/)
9342
- .map((line) => `- ${line}`)
9343
- .join('\n'))}
9344
- `);
9345
- }
9346
-
9347
9810
  /**
9348
9811
  * Client-side safe wrapper for sending emails.
9349
9812
  *
@@ -9537,8 +10000,8 @@ class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
9537
10000
  /**
9538
10001
  * USE IMAGE GENERATOR commitment definition
9539
10002
  *
9540
- * The `USE IMAGE GENERATOR` commitment indicates that the agent should utilize an image generation tool
9541
- * to create images based on text prompts.
10003
+ * The `USE IMAGE GENERATOR` commitment indicates that the agent can output
10004
+ * markdown placeholders for UI-driven image generation.
9542
10005
  *
9543
10006
  * Example usage in agent source:
9544
10007
  *
@@ -9553,11 +10016,14 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
9553
10016
  constructor(type = 'USE IMAGE GENERATOR') {
9554
10017
  super(type, ['USE IMAGE GENERATION', 'IMAGE GENERATOR', 'IMAGE GENERATION', 'USE IMAGE']);
9555
10018
  }
10019
+ get requiresContent() {
10020
+ return false;
10021
+ }
9556
10022
  /**
9557
10023
  * Short one-line description of USE IMAGE GENERATOR.
9558
10024
  */
9559
10025
  get description() {
9560
- return 'Enable the agent to use an image generation tool for creating images from text prompts.';
10026
+ return 'Enable the agent to output markdown image placeholders that the UI turns into generated images.';
9561
10027
  }
9562
10028
  /**
9563
10029
  * Icon for this commitment.
@@ -9572,21 +10038,21 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
9572
10038
  return spaceTrim$1(`
9573
10039
  # USE IMAGE GENERATOR
9574
10040
 
9575
- Enables the agent to use an image generation tool to create images based on text prompts.
10041
+ Enables the agent to output markdown image placeholders that trigger image generation in the user interface.
9576
10042
 
9577
10043
  ## Key aspects
9578
10044
 
9579
10045
  - The content following \`USE IMAGE GENERATOR\` is an arbitrary text that the agent should know (e.g. style instructions or safety guidelines).
9580
- - The actual image generation is handled by the agent runtime using LLM execution tools.
9581
- - Allows the agent to generate visual content based on user requests.
9582
- - Returns the URL of the generated image.
10046
+ - The agent does **not** call an image-generation tool directly.
10047
+ - The agent inserts markdown notation: \`![alt](?image-prompt=...)\`.
10048
+ - The user interface detects the notation and generates the image asynchronously.
9583
10049
 
9584
10050
  ## Examples
9585
10051
 
9586
10052
  \`\`\`book
9587
10053
  Visual Artist
9588
10054
 
9589
- PERSONA You are a creative visual artist who can generate images.
10055
+ PERSONA You are a creative visual artist.
9590
10056
  USE IMAGE GENERATOR
9591
10057
  RULE Always describe the generated image to the user.
9592
10058
  \`\`\`
@@ -9596,80 +10062,28 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
9596
10062
 
9597
10063
  PERSONA You are an interior designer who helps users visualize their space.
9598
10064
  USE IMAGE GENERATOR Professional interior design renders.
9599
- ACTION Generate a preview of the designed room.
10065
+ ACTION Add one generated image placeholder whenever a user asks for a visual.
9600
10066
  \`\`\`
9601
10067
  `);
9602
10068
  }
9603
10069
  applyToAgentModelRequirements(requirements, content) {
9604
- // Get existing tools array or create new one
9605
- const existingTools = requirements.tools || [];
9606
- // Add 'generate_image' to tools if not already present
9607
- const updatedTools = existingTools.some((tool) => tool.name === 'generate_image')
9608
- ? existingTools
9609
- : [
9610
- ...existingTools,
9611
- {
9612
- name: 'generate_image',
9613
- description: spaceTrim$1(`
9614
- Generate an image from a text prompt.
9615
- Use this tool when the user asks to create, draw, or generate an image.
9616
- ${!content ? '' : `Style instructions / guidelines: ${content}`}
9617
- `),
9618
- parameters: {
9619
- type: 'object',
9620
- properties: {
9621
- prompt: {
9622
- type: 'string',
9623
- description: 'The detailed description of the image to generate',
9624
- },
9625
- },
9626
- required: ['prompt'],
9627
- },
9628
- },
9629
- ];
9630
- // Return requirements with updated tools and metadata
10070
+ const extraInstructions = formatOptionalInstructionBlock('Image instructions', content);
9631
10071
  return this.appendToSystemMessage({
9632
10072
  ...requirements,
9633
- tools: updatedTools,
9634
10073
  _metadata: {
9635
10074
  ...requirements._metadata,
9636
10075
  useImageGenerator: content || true,
9637
10076
  },
9638
- }, spaceTrim$1(`
9639
- You have access to an image generator. Use it to create images based on user requests.
9640
- When you generate an image, you will receive a URL of the generated image.
9641
- `));
9642
- }
9643
- /**
9644
- * Gets human-readable titles for tool functions provided by this commitment.
9645
- */
9646
- getToolTitles() {
9647
- return {
9648
- generate_image: 'Generate image',
9649
- };
9650
- }
9651
- /**
9652
- * Gets the `generate_image` tool function implementation.
9653
- */
9654
- getToolFunctions() {
9655
- return {
9656
- async generate_image(args, ...extra) {
9657
- console.log('!!!! [Tool] generate_image called', { args });
9658
- const { prompt } = args;
9659
- if (!prompt) {
9660
- throw new Error('Image prompt is required');
9661
- }
9662
- const { llmTools } = extra[0] || {};
9663
- if (!llmTools || !llmTools.callImageGenerationModel) {
9664
- throw new Error('Image generation is not supported by the current model provider');
9665
- }
9666
- const result = await llmTools.callImageGenerationModel({
9667
- content: prompt,
9668
- modelName: 'dall-e-3', // Defaulting to dall-e-3, but this could be configurable
9669
- });
9670
- return result.content;
9671
- },
9672
- };
10077
+ }, spaceTrim$1((block) => `
10078
+ Image generation:
10079
+ - You do not generate images directly and you do not call any image tool.
10080
+ - When the user asks for an image, include markdown notation in your message:
10081
+ \`![<alt text>](?image-prompt=<prompt>)\`
10082
+ - Keep \`<alt text>\` short and descriptive.
10083
+ - Keep \`<prompt>\` detailed so the generated image matches the request.
10084
+ - You can include normal explanatory text before and after the notation.
10085
+ ${block(extraInstructions)}
10086
+ `));
9673
10087
  }
9674
10088
  }
9675
10089
  /**
@@ -16169,6 +16583,7 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
16169
16583
  systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
16170
16584
  };
16171
16585
  }
16586
+ requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
16172
16587
  // Remove comment lines (lines starting with #) from the final system message
16173
16588
  // while preserving the original content with comments in metadata
16174
16589
  const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
@@ -16177,6 +16592,54 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
16177
16592
  systemMessage: cleanedSystemMessage,
16178
16593
  };
16179
16594
  }
16595
+ /**
16596
+ * @private Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
16597
+ */
16598
+ async function applyPendingInlineKnowledgeSources(requirements, uploader) {
16599
+ var _a;
16600
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
16601
+ if (inlineSources.length === 0) {
16602
+ return requirements;
16603
+ }
16604
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
16605
+ for (const inlineSource of inlineSources) {
16606
+ const url = uploader
16607
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
16608
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
16609
+ knowledgeSources.push(url);
16610
+ }
16611
+ return {
16612
+ ...requirements,
16613
+ knowledgeSources,
16614
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
16615
+ };
16616
+ }
16617
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
16618
+ try {
16619
+ return await uploader(inlineSource);
16620
+ }
16621
+ catch (error) {
16622
+ console.error('[inline-knowledge] Failed to upload inline source', {
16623
+ filename: inlineSource.filename,
16624
+ error,
16625
+ });
16626
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
16627
+ }
16628
+ }
16629
+ function extractInlineKnowledgeSources(metadata) {
16630
+ if (!metadata) {
16631
+ return [];
16632
+ }
16633
+ const value = metadata.inlineKnowledgeSources;
16634
+ return Array.isArray(value) ? value : [];
16635
+ }
16636
+ function stripInlineKnowledgeMetadata(metadata) {
16637
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
16638
+ return metadata;
16639
+ }
16640
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
16641
+ return Object.keys(rest).length > 0 ? rest : undefined;
16642
+ }
16180
16643
  /**
16181
16644
  * Mocked security check for imported files
16182
16645
  *
@@ -17236,6 +17699,28 @@ function mapToolsToOpenAi(tools) {
17236
17699
  }));
17237
17700
  }
17238
17701
 
17702
+ /**
17703
+ * Builds a tool invocation script that injects hidden runtime context into tool args.
17704
+ *
17705
+ * @private utility of OpenAI tool execution wrappers
17706
+ */
17707
+ function buildToolInvocationScript(options) {
17708
+ const { functionName, functionArgsExpression } = options;
17709
+ return `
17710
+ const args = ${functionArgsExpression};
17711
+ const runtimeContextRaw =
17712
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
17713
+ ? undefined
17714
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
17715
+
17716
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
17717
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
17718
+ }
17719
+
17720
+ return await ${functionName}(args);
17721
+ `;
17722
+ }
17723
+
17239
17724
  /**
17240
17725
  * Parses an OpenAI error message to identify which parameter is unsupported
17241
17726
  *
@@ -17589,10 +18074,10 @@ class OpenAiCompatibleExecutionTools {
17589
18074
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
17590
18075
  functionResponse = await scriptTool.execute({
17591
18076
  scriptLanguage: 'javascript',
17592
- script: `
17593
- const args = ${functionArgs};
17594
- return await ${functionName}(args);
17595
- `,
18077
+ script: buildToolInvocationScript({
18078
+ functionName,
18079
+ functionArgsExpression: functionArgs,
18080
+ }),
17596
18081
  parameters: prompt.parameters,
17597
18082
  });
17598
18083
  }
@@ -19294,10 +19779,10 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
19294
19779
  try {
19295
19780
  return await scriptTool.execute({
19296
19781
  scriptLanguage: 'javascript',
19297
- script: `
19298
- const args = ${JSON.stringify(functionArgs)};
19299
- return await ${functionName}(args);
19300
- `,
19782
+ script: buildToolInvocationScript({
19783
+ functionName,
19784
+ functionArgsExpression: JSON.stringify(functionArgs),
19785
+ }),
19301
19786
  parameters: (_c = (_b = runContext === null || runContext === void 0 ? void 0 : runContext.context) === null || _b === void 0 ? void 0 : _b.parameters) !== null && _c !== void 0 ? _c : {},
19302
19787
  });
19303
19788
  }
@@ -19750,10 +20235,10 @@ class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
19750
20235
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
19751
20236
  functionResponse = await scriptTool.execute({
19752
20237
  scriptLanguage: 'javascript',
19753
- script: `
19754
- const args = ${JSON.stringify(functionArgs)};
19755
- return await ${functionName}(args);
19756
- `,
20238
+ script: buildToolInvocationScript({
20239
+ functionName,
20240
+ functionArgsExpression: JSON.stringify(functionArgs),
20241
+ }),
19757
20242
  parameters: prompt.parameters,
19758
20243
  });
19759
20244
  if (this.options.isVerbose) {
@@ -20969,6 +21454,20 @@ async function _Agent_selfLearnTeacher(prompt, result) {
20969
21454
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
20970
21455
  */
20971
21456
 
21457
+ /**
21458
+ * Keep-alive helpers used for streaming chat responses.
21459
+ *
21460
+ * These constants coordinate the signal sent by the Agents Server streaming
21461
+ * endpoint and the parser in the SDK so we can distinguish between
21462
+ * real content and occasional pings.
21463
+ *
21464
+ * @private internal streaming helper for Promptbook chat connections
21465
+ */
21466
+ const CHAT_STREAM_KEEP_ALIVE_TOKEN = 'STREAM_KEEP_ALIVE';
21467
+ /**
21468
+ * Note: [💞] Ignore a discrepancy between file name and entity name
21469
+ */
21470
+
20972
21471
  /**
20973
21472
  * Resolve a remote META IMAGE value into an absolute URL when possible.
20974
21473
  */
@@ -21043,7 +21542,9 @@ class RemoteAgent extends Agent {
21043
21542
  static async connect(options) {
21044
21543
  var _a, _b, _c;
21045
21544
  const agentProfileUrl = `${options.agentUrl}/api/profile`;
21046
- const profileResponse = await fetch(agentProfileUrl);
21545
+ const profileResponse = await fetch(agentProfileUrl, {
21546
+ headers: attachClientVersionHeader(),
21547
+ });
21047
21548
  // <- TODO: [🐱‍🚀] What about closed-source agents?
21048
21549
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
21049
21550
  if (!profileResponse.ok) {
@@ -21144,6 +21645,7 @@ class RemoteAgent extends Agent {
21144
21645
  }
21145
21646
  const response = await fetch(`${this.agentUrl}/api/voice`, {
21146
21647
  method: 'POST',
21648
+ headers: attachClientVersionHeader(),
21147
21649
  body: formData,
21148
21650
  });
21149
21651
  if (!response.ok) {
@@ -21173,13 +21675,14 @@ class RemoteAgent extends Agent {
21173
21675
  const chatPrompt = prompt;
21174
21676
  const bookResponse = await fetch(`${this.agentUrl}/api/chat`, {
21175
21677
  method: 'POST',
21176
- headers: {
21678
+ headers: attachClientVersionHeader({
21177
21679
  'Content-Type': 'application/json',
21178
- },
21680
+ }),
21179
21681
  body: JSON.stringify({
21180
21682
  message: prompt.content,
21181
21683
  thread: chatPrompt.thread,
21182
21684
  attachments: chatPrompt.attachments,
21685
+ parameters: chatPrompt.parameters,
21183
21686
  }),
21184
21687
  });
21185
21688
  // <- TODO: [🐱‍🚀] What about closed-source agents?
@@ -21261,6 +21764,9 @@ class RemoteAgent extends Agent {
21261
21764
  const lines = textChunk.split(/\r?\n/);
21262
21765
  for (const line of lines) {
21263
21766
  const trimmedLine = line.trim();
21767
+ if (trimmedLine === CHAT_STREAM_KEEP_ALIVE_TOKEN) {
21768
+ continue;
21769
+ }
21264
21770
  let isToolCallLine = false;
21265
21771
  if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
21266
21772
  try {