@promptbook/remote-server 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
@@ -40,7 +40,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
40
40
  * @generated
41
41
  * @see https://github.com/webgptorg/promptbook
42
42
  */
43
- const PROMPTBOOK_ENGINE_VERSION = '0.110.0';
43
+ const PROMPTBOOK_ENGINE_VERSION = '0.111.0-1';
44
44
  /**
45
45
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
46
46
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -8447,6 +8447,36 @@ function prompt(strings, ...values) {
8447
8447
  * Note: [💞] Ignore a discrepancy between file name and entity name
8448
8448
  */
8449
8449
 
8450
+ /**
8451
+ * HTTP header used by Promptbook clients to advertise their release version.
8452
+ *
8453
+ * @public exported from `@promptbook/utils`
8454
+ */
8455
+ const CLIENT_VERSION_HEADER = 'x-promptbook-client-version';
8456
+ /**
8457
+ * The latest client (engine) version that the server expects.
8458
+ *
8459
+ * @public exported from `@promptbook/utils`
8460
+ */
8461
+ const CLIENT_LATEST_VERSION = PROMPTBOOK_ENGINE_VERSION;
8462
+ /**
8463
+ * Creates a headers object that includes the client version header.
8464
+ *
8465
+ * @param headers - Optional base headers to clone.
8466
+ * @returns New headers object augmented with `CLIENT_VERSION_HEADER`.
8467
+ *
8468
+ * @public exported from `@promptbook/utils`
8469
+ */
8470
+ function attachClientVersionHeader(headers) {
8471
+ return {
8472
+ ...(headers !== null && headers !== void 0 ? headers : {}),
8473
+ [CLIENT_VERSION_HEADER]: CLIENT_LATEST_VERSION,
8474
+ };
8475
+ }
8476
+ /**
8477
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8478
+ */
8479
+
8450
8480
  /**
8451
8481
  * Computes SHA-256 hash of the given object
8452
8482
  *
@@ -11647,28 +11677,14 @@ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
11647
11677
  * Note: [💞] Ignore a discrepancy between file name and entity name
11648
11678
  */
11649
11679
 
11650
- /**
11651
- * @@@
11652
- *
11653
- * @private thing of inline knowledge
11654
- */
11680
+ /** @private The default base name for inline knowledge files when the content lacks identifying text */
11655
11681
  const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';
11656
- /**
11657
- * @@@
11658
- *
11659
- * @private thing of inline knowledge
11660
- */
11682
+ /** @private The default file extension used for inline knowledge uploads */
11661
11683
  const INLINE_KNOWLEDGE_EXTENSION = '.txt';
11662
- /**
11663
- * @@@
11664
- *
11665
- * @private thing of inline knowledge
11666
- */
11684
+ /** @private Prefix that identifies base64 data URLs */
11667
11685
  const DATA_URL_PREFIX = 'data:';
11668
11686
  /**
11669
- * @@@
11670
- *
11671
- * @private thing of inline knowledge
11687
+ * @private Retrieves the first meaningful line from the inline content.
11672
11688
  */
11673
11689
  function getFirstNonEmptyLine(content) {
11674
11690
  const lines = content.split(/\r?\n/);
@@ -11681,9 +11697,7 @@ function getFirstNonEmptyLine(content) {
11681
11697
  return null;
11682
11698
  }
11683
11699
  /**
11684
- * @@@
11685
- *
11686
- * @private thing of inline knowledge
11700
+ * @private Determines the base file name by normalizing the first non-empty line.
11687
11701
  */
11688
11702
  function deriveBaseFilename(content) {
11689
11703
  const firstLine = getFirstNonEmptyLine(content);
@@ -11694,22 +11708,18 @@ function deriveBaseFilename(content) {
11694
11708
  return normalized || INLINE_KNOWLEDGE_BASE_NAME;
11695
11709
  }
11696
11710
  /**
11697
- * Creates a data URL that represents the inline knowledge content as a text file.
11698
- *
11699
- * @private thing of inline knowledge
11711
+ * @private Converts inline knowledge into the internal metadata form used for uploads.
11700
11712
  */
11701
11713
  function createInlineKnowledgeSourceFile(content) {
11702
11714
  const trimmedContent = content.trim();
11703
11715
  const baseName = deriveBaseFilename(trimmedContent);
11704
11716
  const filename = `${baseName}${INLINE_KNOWLEDGE_EXTENSION}`;
11705
11717
  const mimeType = 'text/plain';
11706
- const base64 = Buffer.from(trimmedContent, 'utf-8').toString('base64');
11707
- const encodedFilename = encodeURIComponent(filename);
11708
- const url = `${DATA_URL_PREFIX}${mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
11718
+ const buffer = Buffer.from(trimmedContent, 'utf-8');
11709
11719
  return {
11710
11720
  filename,
11711
11721
  mimeType,
11712
- url,
11722
+ buffer,
11713
11723
  };
11714
11724
  }
11715
11725
  /**
@@ -11720,10 +11730,18 @@ function createInlineKnowledgeSourceFile(content) {
11720
11730
  function isDataUrlKnowledgeSource(source) {
11721
11731
  return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);
11722
11732
  }
11733
+ /**
11734
+ * @private Converts a stored inline knowledge file into a data URL for backwards compatibility.
11735
+ */
11736
+ function inlineKnowledgeSourceToDataUrl(source) {
11737
+ const base64 = source.buffer.toString('base64');
11738
+ const encodedFilename = encodeURIComponent(source.filename);
11739
+ return `${DATA_URL_PREFIX}${source.mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
11740
+ }
11723
11741
  /**
11724
11742
  * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.
11725
11743
  *
11726
- * @private thing of inline knowledge
11744
+ * @private utility of inline knowledge processing
11727
11745
  */
11728
11746
  function parseDataUrlKnowledgeSource(source) {
11729
11747
  if (!isDataUrlKnowledgeSource(source)) {
@@ -11856,6 +11874,7 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
11856
11874
  `);
11857
11875
  }
11858
11876
  applyToAgentModelRequirements(requirements, content) {
11877
+ var _a;
11859
11878
  const trimmedContent = content.trim();
11860
11879
  if (!trimmedContent) {
11861
11880
  return requirements;
@@ -11876,9 +11895,13 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
11876
11895
  }
11877
11896
  else {
11878
11897
  const inlineSource = createInlineKnowledgeSourceFile(trimmedContent);
11898
+ const existingInlineSources = (((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.inlineKnowledgeSources) || []).slice();
11879
11899
  const updatedRequirements = {
11880
11900
  ...requirements,
11881
- knowledgeSources: [...(requirements.knowledgeSources || []), inlineSource.url],
11901
+ _metadata: {
11902
+ ...requirements._metadata,
11903
+ inlineKnowledgeSources: [...existingInlineSources, inlineSource],
11904
+ },
11882
11905
  };
11883
11906
  const knowledgeInfo = `Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`;
11884
11907
  return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
@@ -11960,6 +11983,237 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
11960
11983
  * Note: [💞] Ignore a discrepancy between file name and entity name
11961
11984
  */
11962
11985
 
11986
+ /**
11987
+ * @@@
11988
+ *
11989
+ * @private utility for commitments
11990
+ */
11991
+ function formatOptionalInstructionBlock(label, content) {
11992
+ const trimmedContent = spaceTrim$1(content);
11993
+ if (!trimmedContent) {
11994
+ return '';
11995
+ }
11996
+ return spaceTrim$1((block) => `
11997
+ - ${label}:
11998
+ ${block(trimmedContent
11999
+ .split(/\r?\n/)
12000
+ .map((line) => `- ${line}`)
12001
+ .join('\n'))}
12002
+ `);
12003
+ }
12004
+
12005
+ /**
12006
+ * Prompt parameter key used to pass hidden runtime context to tool execution.
12007
+ *
12008
+ * @private internal runtime wiring for commitment tools
12009
+ */
12010
+ const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
12011
+ /**
12012
+ * Hidden argument key used to pass runtime context into individual tool calls.
12013
+ *
12014
+ * @private internal runtime wiring for commitment tools
12015
+ */
12016
+ const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
12017
+ /**
12018
+ * Parses unknown runtime context payload into a normalized object.
12019
+ *
12020
+ * @private internal runtime wiring for commitment tools
12021
+ */
12022
+ function parseToolRuntimeContext(rawValue) {
12023
+ if (!rawValue) {
12024
+ return null;
12025
+ }
12026
+ let parsed = rawValue;
12027
+ if (typeof rawValue === 'string') {
12028
+ try {
12029
+ parsed = JSON.parse(rawValue);
12030
+ }
12031
+ catch (_a) {
12032
+ return null;
12033
+ }
12034
+ }
12035
+ if (!parsed || typeof parsed !== 'object') {
12036
+ return null;
12037
+ }
12038
+ return parsed;
12039
+ }
12040
+ /**
12041
+ * Reads runtime context attached to tool call arguments.
12042
+ *
12043
+ * @private internal runtime wiring for commitment tools
12044
+ */
12045
+ function readToolRuntimeContextFromToolArgs(args) {
12046
+ return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
12047
+ }
12048
+ /**
12049
+ * Serializes runtime context for prompt parameters.
12050
+ *
12051
+ * @private internal runtime wiring for commitment tools
12052
+ */
12053
+ function serializeToolRuntimeContext(context) {
12054
+ return JSON.stringify(context);
12055
+ }
12056
+ /**
12057
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12058
+ */
12059
+
12060
+ /**
12061
+ * Tool name used to retrieve persisted user memory.
12062
+ *
12063
+ * @private internal MEMORY commitment constant
12064
+ */
12065
+ const RETRIEVE_USER_MEMORY_TOOL_NAME = 'retrieve_user_memory';
12066
+ /**
12067
+ * Tool name used to store persisted user memory.
12068
+ *
12069
+ * @private internal MEMORY commitment constant
12070
+ */
12071
+ const STORE_USER_MEMORY_TOOL_NAME = 'store_user_memory';
12072
+ const UPDATE_USER_MEMORY_TOOL_NAME = 'update_user_memory';
12073
+ const DELETE_USER_MEMORY_TOOL_NAME = 'delete_user_memory';
12074
+ /**
12075
+ * Resolves runtime context from hidden tool arguments.
12076
+ *
12077
+ * @private utility of MEMORY commitment
12078
+ */
12079
+ function resolveMemoryRuntimeContext(args) {
12080
+ const runtimeContext = readToolRuntimeContextFromToolArgs(args);
12081
+ const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
12082
+ return {
12083
+ enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
12084
+ userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
12085
+ username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
12086
+ agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
12087
+ agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
12088
+ isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
12089
+ };
12090
+ }
12091
+ /**
12092
+ * Builds a disabled memory-tool response payload.
12093
+ *
12094
+ * @private utility of MEMORY commitment
12095
+ */
12096
+ function createDisabledMemoryResult(action, message) {
12097
+ if (action === 'retrieve') {
12098
+ return {
12099
+ action,
12100
+ status: 'disabled',
12101
+ memories: [],
12102
+ message,
12103
+ };
12104
+ }
12105
+ if (action === 'store') {
12106
+ return {
12107
+ action,
12108
+ status: 'disabled',
12109
+ message,
12110
+ };
12111
+ }
12112
+ if (action === 'update') {
12113
+ return {
12114
+ action,
12115
+ status: 'disabled',
12116
+ message,
12117
+ };
12118
+ }
12119
+ if (action === 'delete') {
12120
+ return {
12121
+ action,
12122
+ status: 'disabled',
12123
+ message,
12124
+ };
12125
+ }
12126
+ throw new Error(`Unsupported memory tool action: ${action}`);
12127
+ }
12128
+ /**
12129
+ * Gets the runtime adapter and returns a disabled result when unavailable.
12130
+ *
12131
+ * @private utility of MEMORY commitment
12132
+ */
12133
+ function getRuntimeAdapterOrDisabledResult(action, runtimeContext) {
12134
+ if (!runtimeContext.enabled || runtimeContext.isTeamConversation) {
12135
+ return {
12136
+ adapter: null,
12137
+ disabledResult: createDisabledMemoryResult(action, runtimeContext.isTeamConversation
12138
+ ? 'Memory is disabled for TEAM conversations.'
12139
+ : 'Memory is disabled for unauthenticated users.'),
12140
+ };
12141
+ }
12142
+ {
12143
+ return {
12144
+ adapter: null,
12145
+ disabledResult: createDisabledMemoryResult(action, 'Memory runtime is not available in this environment.'),
12146
+ };
12147
+ }
12148
+ }
12149
+ /**
12150
+ * Parses retrieve memory arguments.
12151
+ *
12152
+ * @private utility of MEMORY commitment
12153
+ */
12154
+ function parseRetrieveMemoryArgs(args) {
12155
+ const query = typeof args.query === 'string' ? args.query.trim() : undefined;
12156
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
12157
+ return {
12158
+ query: query && query.length > 0 ? query : undefined,
12159
+ limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
12160
+ };
12161
+ }
12162
+ /**
12163
+ * Parses store memory arguments.
12164
+ *
12165
+ * @private utility of MEMORY commitment
12166
+ */
12167
+ function parseStoreMemoryArgs(args) {
12168
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
12169
+ if (!content) {
12170
+ throw new Error('Memory content is required.');
12171
+ }
12172
+ return {
12173
+ content,
12174
+ isGlobal: args.isGlobal === true,
12175
+ };
12176
+ }
12177
+ /**
12178
+ * Parses a memory identifier argument shared across MEMORY tools.
12179
+ *
12180
+ * @private utility of MEMORY commitment
12181
+ */
12182
+ function parseMemoryIdArg(value) {
12183
+ const memoryId = typeof value === 'string' ? value.trim() : '';
12184
+ if (!memoryId) {
12185
+ throw new Error('Memory id is required.');
12186
+ }
12187
+ return memoryId;
12188
+ }
12189
+ /**
12190
+ * Parses update memory arguments.
12191
+ *
12192
+ * @private utility of MEMORY commitment
12193
+ */
12194
+ function parseUpdateMemoryArgs(args) {
12195
+ const memoryId = parseMemoryIdArg(args.memoryId);
12196
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
12197
+ if (!content) {
12198
+ throw new Error('Memory content is required.');
12199
+ }
12200
+ const isGlobal = typeof args.isGlobal === 'boolean' ? args.isGlobal : undefined;
12201
+ return {
12202
+ memoryId,
12203
+ content,
12204
+ isGlobal,
12205
+ };
12206
+ }
12207
+ /**
12208
+ * Parses delete memory arguments.
12209
+ *
12210
+ * @private utility of MEMORY commitment
12211
+ */
12212
+ function parseDeleteMemoryArgs(args) {
12213
+ return {
12214
+ memoryId: parseMemoryIdArg(args.memoryId),
12215
+ };
12216
+ }
11963
12217
  /**
11964
12218
  * MEMORY commitment definition
11965
12219
  *
@@ -11981,6 +12235,9 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
11981
12235
  constructor(type = 'MEMORY') {
11982
12236
  super(type);
11983
12237
  }
12238
+ get requiresContent() {
12239
+ return false;
12240
+ }
11984
12241
  /**
11985
12242
  * Short one-line description of MEMORY.
11986
12243
  */
@@ -12000,21 +12257,14 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
12000
12257
  return spaceTrim$1(`
12001
12258
  # ${this.type}
12002
12259
 
12003
- 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.
12260
+ Enables persistent user memory for the current agent. The memory is stored by the runtime and can be retrieved in future conversations.
12004
12261
 
12005
12262
  ## Key aspects
12006
12263
 
12007
- - Both terms work identically and can be used interchangeably.
12008
- - Focuses on user-specific information and interaction history.
12009
- - Helps personalize responses based on past interactions.
12010
- - Maintains continuity across conversations.
12011
-
12012
- ## Differences from KNOWLEDGE
12013
-
12014
- - \`KNOWLEDGE\` is for domain expertise and factual information
12015
- - \`MEMORY\` is for user-specific context and preferences
12016
- - \`MEMORY\` creates more personalized interactions
12017
- - \`MEMORY\` often includes temporal or preference-based information
12264
+ - Both \`MEMORY\` and \`MEMORIES\` work identically.
12265
+ - Stores user-specific details through runtime tools.
12266
+ - Retrieves relevant memories for personalized responses.
12267
+ - Supports optional extra instructions in the commitment content.
12018
12268
 
12019
12269
  ## Examples
12020
12270
 
@@ -12022,10 +12272,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
12022
12272
  Personal Assistant
12023
12273
 
12024
12274
  PERSONA You are a personal productivity assistant
12025
- MEMORY User is a software developer working in JavaScript/React
12026
- MEMORY User prefers morning work sessions and afternoon meetings
12027
- MEMORY Previously helped with project planning for mobile apps
12028
- MEMORY User timezone: UTC-8 (Pacific Time)
12275
+ MEMORY Remember user projects and long-term preferences.
12029
12276
  GOAL Help optimize daily productivity and workflow
12030
12277
  \`\`\`
12031
12278
 
@@ -12033,10 +12280,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
12033
12280
  Learning Companion
12034
12281
 
12035
12282
  PERSONA You are an educational companion for programming students
12036
- MEMORY Student is learning Python as their first programming language
12037
- MEMORY Previous topics covered: variables, loops, functions
12038
- MEMORY Student learns best with practical examples and exercises
12039
- MEMORY Last session: working on list comprehensions
12283
+ MEMORY Remember only the student's learning progress and preferred study style.
12040
12284
  GOAL Provide progressive learning experiences tailored to student's pace
12041
12285
  \`\`\`
12042
12286
 
@@ -12044,23 +12288,245 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
12044
12288
  Customer Support Agent
12045
12289
 
12046
12290
  PERSONA You are a customer support representative
12047
- MEMORY Customer has premium subscription since 2023
12048
- MEMORY Previous issue: billing question resolved last month
12049
- MEMORY Customer prefers email communication over phone calls
12050
- MEMORY Account shows frequent use of advanced features
12291
+ MEMORY Remember only important support history and communication preferences.
12051
12292
  GOAL Provide personalized support based on customer history
12052
12293
  \`\`\`
12053
12294
  `);
12054
12295
  }
12055
12296
  applyToAgentModelRequirements(requirements, content) {
12056
- const trimmedContent = content.trim();
12057
- if (!trimmedContent) {
12058
- return requirements;
12297
+ const extraInstructions = formatOptionalInstructionBlock('Memory instructions', content);
12298
+ const existingTools = requirements.tools || [];
12299
+ const tools = [...existingTools];
12300
+ if (!tools.some((tool) => tool.name === RETRIEVE_USER_MEMORY_TOOL_NAME)) {
12301
+ tools.push({
12302
+ name: RETRIEVE_USER_MEMORY_TOOL_NAME,
12303
+ description: spaceTrim$1(`
12304
+ Retrieve previously stored user memories relevant to the current conversation.
12305
+ Use this before responding when user context can improve the answer.
12306
+ `),
12307
+ parameters: {
12308
+ type: 'object',
12309
+ properties: {
12310
+ query: {
12311
+ type: 'string',
12312
+ description: 'Optional query used to filter relevant memories.',
12313
+ },
12314
+ limit: {
12315
+ type: 'integer',
12316
+ description: 'Optional maximum number of memories to return (default 5, max 20).',
12317
+ },
12318
+ },
12319
+ },
12320
+ });
12321
+ }
12322
+ if (!tools.some((tool) => tool.name === STORE_USER_MEMORY_TOOL_NAME)) {
12323
+ tools.push({
12324
+ name: STORE_USER_MEMORY_TOOL_NAME,
12325
+ description: spaceTrim$1(`
12326
+ Store a durable user memory that should be remembered in future conversations.
12327
+ Store only stable and useful user-specific facts or preferences.
12328
+ `),
12329
+ parameters: {
12330
+ type: 'object',
12331
+ properties: {
12332
+ content: {
12333
+ type: 'string',
12334
+ description: 'Memory text to store.',
12335
+ },
12336
+ isGlobal: {
12337
+ type: 'boolean',
12338
+ description: 'Set true to make this memory global across all user agents.',
12339
+ },
12340
+ },
12341
+ required: ['content'],
12342
+ },
12343
+ });
12344
+ }
12345
+ if (!tools.some((tool) => tool.name === UPDATE_USER_MEMORY_TOOL_NAME)) {
12346
+ tools.push({
12347
+ name: UPDATE_USER_MEMORY_TOOL_NAME,
12348
+ description: spaceTrim$1(`
12349
+ Update an existing user memory after retrieving it, so the stored fact stays accurate.
12350
+ Always pass the memory id you retrieved along with the new content.
12351
+ `),
12352
+ parameters: {
12353
+ type: 'object',
12354
+ properties: {
12355
+ memoryId: {
12356
+ type: 'string',
12357
+ description: 'Unique identifier of the memory entry to update.',
12358
+ },
12359
+ content: {
12360
+ type: 'string',
12361
+ description: 'Updated memory text.',
12362
+ },
12363
+ isGlobal: {
12364
+ type: 'boolean',
12365
+ description: 'Set true to keep the fact global; omit or false to keep it agent-scoped.',
12366
+ },
12367
+ },
12368
+ required: ['memoryId', 'content'],
12369
+ },
12370
+ });
12059
12371
  }
12060
- // Create memory section for system message
12061
- const memorySection = `Memory: ${trimmedContent}`;
12062
- // Memory information is contextual and should be included in the system message
12063
- return this.appendToSystemMessage(requirements, memorySection, '\n\n');
12372
+ if (!tools.some((tool) => tool.name === DELETE_USER_MEMORY_TOOL_NAME)) {
12373
+ tools.push({
12374
+ name: DELETE_USER_MEMORY_TOOL_NAME,
12375
+ description: spaceTrim$1(`
12376
+ Delete a user memory that is no longer relevant. Deletions are soft so the record is hidden from future queries.
12377
+ `),
12378
+ parameters: {
12379
+ type: 'object',
12380
+ properties: {
12381
+ memoryId: {
12382
+ type: 'string',
12383
+ description: 'Unique identifier of the memory entry to delete.',
12384
+ },
12385
+ },
12386
+ required: ['memoryId'],
12387
+ },
12388
+ });
12389
+ }
12390
+ return this.appendToSystemMessage({
12391
+ ...requirements,
12392
+ tools,
12393
+ _metadata: {
12394
+ ...requirements._metadata,
12395
+ useMemory: content || true,
12396
+ },
12397
+ }, spaceTrim$1((block) => `
12398
+ Memory:
12399
+ - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
12400
+ - You can use persistent user memory tools.
12401
+ - Use "${RETRIEVE_USER_MEMORY_TOOL_NAME}" to load relevant memory before answering.
12402
+ - Use "${STORE_USER_MEMORY_TOOL_NAME}" to save stable user-specific facts that improve future help.
12403
+ - Use "${UPDATE_USER_MEMORY_TOOL_NAME}" to refresh an existing memory when the content changes.
12404
+ - Use "${DELETE_USER_MEMORY_TOOL_NAME}" to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
12405
+ - Store concise memory items and avoid duplicates.
12406
+ - Never claim memory was saved or loaded unless the tool confirms it.
12407
+ ${block(extraInstructions)}
12408
+ `));
12409
+ }
12410
+ /**
12411
+ * Gets human-readable titles for MEMORY tool functions.
12412
+ */
12413
+ getToolTitles() {
12414
+ return {
12415
+ [RETRIEVE_USER_MEMORY_TOOL_NAME]: 'User memory',
12416
+ [STORE_USER_MEMORY_TOOL_NAME]: 'Store user memory',
12417
+ [UPDATE_USER_MEMORY_TOOL_NAME]: 'Update user memory',
12418
+ [DELETE_USER_MEMORY_TOOL_NAME]: 'Delete user memory',
12419
+ };
12420
+ }
12421
+ /**
12422
+ * Gets MEMORY tool function implementations.
12423
+ */
12424
+ getToolFunctions() {
12425
+ return {
12426
+ async [RETRIEVE_USER_MEMORY_TOOL_NAME](args) {
12427
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12428
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
12429
+ if (!adapter || disabledResult) {
12430
+ return JSON.stringify(disabledResult);
12431
+ }
12432
+ const parsedArgs = parseRetrieveMemoryArgs(args);
12433
+ try {
12434
+ const memories = await adapter.retrieveMemories(parsedArgs, runtimeContext);
12435
+ const result = {
12436
+ action: 'retrieve',
12437
+ status: 'ok',
12438
+ query: parsedArgs.query,
12439
+ memories,
12440
+ };
12441
+ return JSON.stringify(result);
12442
+ }
12443
+ catch (error) {
12444
+ const result = {
12445
+ action: 'retrieve',
12446
+ status: 'error',
12447
+ query: parsedArgs.query,
12448
+ memories: [],
12449
+ message: error instanceof Error ? error.message : String(error),
12450
+ };
12451
+ return JSON.stringify(result);
12452
+ }
12453
+ },
12454
+ async [STORE_USER_MEMORY_TOOL_NAME](args) {
12455
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12456
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('store', runtimeContext);
12457
+ if (!adapter || disabledResult) {
12458
+ return JSON.stringify(disabledResult);
12459
+ }
12460
+ try {
12461
+ const parsedArgs = parseStoreMemoryArgs(args);
12462
+ const memory = await adapter.storeMemory(parsedArgs, runtimeContext);
12463
+ const result = {
12464
+ action: 'store',
12465
+ status: 'stored',
12466
+ memory,
12467
+ };
12468
+ return JSON.stringify(result);
12469
+ }
12470
+ catch (error) {
12471
+ const result = {
12472
+ action: 'store',
12473
+ status: 'error',
12474
+ message: error instanceof Error ? error.message : String(error),
12475
+ };
12476
+ return JSON.stringify(result);
12477
+ }
12478
+ },
12479
+ async [UPDATE_USER_MEMORY_TOOL_NAME](args) {
12480
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12481
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('update', runtimeContext);
12482
+ if (!adapter || disabledResult) {
12483
+ return JSON.stringify(disabledResult);
12484
+ }
12485
+ try {
12486
+ const parsedArgs = parseUpdateMemoryArgs(args);
12487
+ const memory = await adapter.updateMemory(parsedArgs, runtimeContext);
12488
+ const result = {
12489
+ action: 'update',
12490
+ status: 'updated',
12491
+ memory,
12492
+ };
12493
+ return JSON.stringify(result);
12494
+ }
12495
+ catch (error) {
12496
+ const result = {
12497
+ action: 'update',
12498
+ status: 'error',
12499
+ message: error instanceof Error ? error.message : String(error),
12500
+ };
12501
+ return JSON.stringify(result);
12502
+ }
12503
+ },
12504
+ async [DELETE_USER_MEMORY_TOOL_NAME](args) {
12505
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12506
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('delete', runtimeContext);
12507
+ if (!adapter || disabledResult) {
12508
+ return JSON.stringify(disabledResult);
12509
+ }
12510
+ try {
12511
+ const parsedArgs = parseDeleteMemoryArgs(args);
12512
+ const deleted = await adapter.deleteMemory(parsedArgs, runtimeContext);
12513
+ const result = {
12514
+ action: 'delete',
12515
+ status: 'deleted',
12516
+ memoryId: deleted.id,
12517
+ };
12518
+ return JSON.stringify(result);
12519
+ }
12520
+ catch (error) {
12521
+ const result = {
12522
+ action: 'delete',
12523
+ status: 'error',
12524
+ message: error instanceof Error ? error.message : String(error),
12525
+ };
12526
+ return JSON.stringify(result);
12527
+ }
12528
+ },
12529
+ };
12064
12530
  }
12065
12531
  }
12066
12532
  /**
@@ -14173,14 +14639,30 @@ function buildTeammateRequest(message, context) {
14173
14639
  /**
14174
14640
  * Builds a minimal chat prompt for teammate calls.
14175
14641
  */
14176
- function buildTeammatePrompt(request) {
14642
+ function buildTeammatePrompt(request, runtimeContext) {
14177
14643
  return {
14178
14644
  title: 'Teammate consultation',
14179
14645
  modelRequirements: {
14180
14646
  modelVariant: 'CHAT',
14181
14647
  },
14182
14648
  content: request,
14183
- parameters: {},
14649
+ parameters: {
14650
+ [TOOL_RUNTIME_CONTEXT_PARAMETER]: serializeToolRuntimeContext(runtimeContext),
14651
+ },
14652
+ };
14653
+ }
14654
+ /**
14655
+ * Creates teammate runtime context and marks conversation as team-only memory-disabled.
14656
+ */
14657
+ function createTeamConversationRuntimeContext(value) {
14658
+ const runtimeContext = parseToolRuntimeContext(value) || {};
14659
+ return {
14660
+ ...runtimeContext,
14661
+ memory: {
14662
+ ...(runtimeContext.memory || {}),
14663
+ enabled: false,
14664
+ isTeamConversation: true,
14665
+ },
14184
14666
  };
14185
14667
  }
14186
14668
  /**
@@ -14224,7 +14706,7 @@ function createTeamToolFunction(entry) {
14224
14706
  let toolCalls;
14225
14707
  try {
14226
14708
  const remoteAgent = await getRemoteTeammateAgent(entry.teammate.url);
14227
- const prompt = buildTeammatePrompt(request);
14709
+ const prompt = buildTeammatePrompt(request, createTeamConversationRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]));
14228
14710
  const teammateResult = await remoteAgent.callChatModel(prompt);
14229
14711
  response = teammateResult.content || '';
14230
14712
  toolCalls =
@@ -14774,25 +15256,6 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
14774
15256
  * Note: [💞] Ignore a discrepancy between file name and entity name
14775
15257
  */
14776
15258
 
14777
- /**
14778
- * @@@
14779
- *
14780
- * @private utility for commitments
14781
- */
14782
- function formatOptionalInstructionBlock(label, content) {
14783
- const trimmedContent = spaceTrim$1(content);
14784
- if (!trimmedContent) {
14785
- return '';
14786
- }
14787
- return spaceTrim$1((block) => `
14788
- - ${label}:
14789
- ${block(trimmedContent
14790
- .split(/\r?\n/)
14791
- .map((line) => `- ${line}`)
14792
- .join('\n'))}
14793
- `);
14794
- }
14795
-
14796
15259
  /**
14797
15260
  * Client-side safe wrapper for sending emails.
14798
15261
  *
@@ -14986,8 +15449,8 @@ class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
14986
15449
  /**
14987
15450
  * USE IMAGE GENERATOR commitment definition
14988
15451
  *
14989
- * The `USE IMAGE GENERATOR` commitment indicates that the agent should utilize an image generation tool
14990
- * to create images based on text prompts.
15452
+ * The `USE IMAGE GENERATOR` commitment indicates that the agent can output
15453
+ * markdown placeholders for UI-driven image generation.
14991
15454
  *
14992
15455
  * Example usage in agent source:
14993
15456
  *
@@ -15002,11 +15465,14 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
15002
15465
  constructor(type = 'USE IMAGE GENERATOR') {
15003
15466
  super(type, ['USE IMAGE GENERATION', 'IMAGE GENERATOR', 'IMAGE GENERATION', 'USE IMAGE']);
15004
15467
  }
15468
+ get requiresContent() {
15469
+ return false;
15470
+ }
15005
15471
  /**
15006
15472
  * Short one-line description of USE IMAGE GENERATOR.
15007
15473
  */
15008
15474
  get description() {
15009
- return 'Enable the agent to use an image generation tool for creating images from text prompts.';
15475
+ return 'Enable the agent to output markdown image placeholders that the UI turns into generated images.';
15010
15476
  }
15011
15477
  /**
15012
15478
  * Icon for this commitment.
@@ -15021,21 +15487,21 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
15021
15487
  return spaceTrim$1(`
15022
15488
  # USE IMAGE GENERATOR
15023
15489
 
15024
- Enables the agent to use an image generation tool to create images based on text prompts.
15490
+ Enables the agent to output markdown image placeholders that trigger image generation in the user interface.
15025
15491
 
15026
15492
  ## Key aspects
15027
15493
 
15028
15494
  - The content following \`USE IMAGE GENERATOR\` is an arbitrary text that the agent should know (e.g. style instructions or safety guidelines).
15029
- - The actual image generation is handled by the agent runtime using LLM execution tools.
15030
- - Allows the agent to generate visual content based on user requests.
15031
- - Returns the URL of the generated image.
15495
+ - The agent does **not** call an image-generation tool directly.
15496
+ - The agent inserts markdown notation: \`![alt](?image-prompt=...)\`.
15497
+ - The user interface detects the notation and generates the image asynchronously.
15032
15498
 
15033
15499
  ## Examples
15034
15500
 
15035
15501
  \`\`\`book
15036
15502
  Visual Artist
15037
15503
 
15038
- PERSONA You are a creative visual artist who can generate images.
15504
+ PERSONA You are a creative visual artist.
15039
15505
  USE IMAGE GENERATOR
15040
15506
  RULE Always describe the generated image to the user.
15041
15507
  \`\`\`
@@ -15045,80 +15511,28 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
15045
15511
 
15046
15512
  PERSONA You are an interior designer who helps users visualize their space.
15047
15513
  USE IMAGE GENERATOR Professional interior design renders.
15048
- ACTION Generate a preview of the designed room.
15514
+ ACTION Add one generated image placeholder whenever a user asks for a visual.
15049
15515
  \`\`\`
15050
15516
  `);
15051
15517
  }
15052
15518
  applyToAgentModelRequirements(requirements, content) {
15053
- // Get existing tools array or create new one
15054
- const existingTools = requirements.tools || [];
15055
- // Add 'generate_image' to tools if not already present
15056
- const updatedTools = existingTools.some((tool) => tool.name === 'generate_image')
15057
- ? existingTools
15058
- : [
15059
- ...existingTools,
15060
- {
15061
- name: 'generate_image',
15062
- description: spaceTrim$1(`
15063
- Generate an image from a text prompt.
15064
- Use this tool when the user asks to create, draw, or generate an image.
15065
- ${!content ? '' : `Style instructions / guidelines: ${content}`}
15066
- `),
15067
- parameters: {
15068
- type: 'object',
15069
- properties: {
15070
- prompt: {
15071
- type: 'string',
15072
- description: 'The detailed description of the image to generate',
15073
- },
15074
- },
15075
- required: ['prompt'],
15076
- },
15077
- },
15078
- ];
15079
- // Return requirements with updated tools and metadata
15519
+ const extraInstructions = formatOptionalInstructionBlock('Image instructions', content);
15080
15520
  return this.appendToSystemMessage({
15081
15521
  ...requirements,
15082
- tools: updatedTools,
15083
15522
  _metadata: {
15084
15523
  ...requirements._metadata,
15085
15524
  useImageGenerator: content || true,
15086
15525
  },
15087
- }, spaceTrim$1(`
15088
- You have access to an image generator. Use it to create images based on user requests.
15089
- When you generate an image, you will receive a URL of the generated image.
15090
- `));
15091
- }
15092
- /**
15093
- * Gets human-readable titles for tool functions provided by this commitment.
15094
- */
15095
- getToolTitles() {
15096
- return {
15097
- generate_image: 'Generate image',
15098
- };
15099
- }
15100
- /**
15101
- * Gets the `generate_image` tool function implementation.
15102
- */
15103
- getToolFunctions() {
15104
- return {
15105
- async generate_image(args, ...extra) {
15106
- console.log('!!!! [Tool] generate_image called', { args });
15107
- const { prompt } = args;
15108
- if (!prompt) {
15109
- throw new Error('Image prompt is required');
15110
- }
15111
- const { llmTools } = extra[0] || {};
15112
- if (!llmTools || !llmTools.callImageGenerationModel) {
15113
- throw new Error('Image generation is not supported by the current model provider');
15114
- }
15115
- const result = await llmTools.callImageGenerationModel({
15116
- content: prompt,
15117
- modelName: 'dall-e-3', // Defaulting to dall-e-3, but this could be configurable
15118
- });
15119
- return result.content;
15120
- },
15121
- };
15526
+ }, spaceTrim$1((block) => `
15527
+ Image generation:
15528
+ - You do not generate images directly and you do not call any image tool.
15529
+ - When the user asks for an image, include markdown notation in your message:
15530
+ \`![<alt text>](?image-prompt=<prompt>)\`
15531
+ - Keep \`<alt text>\` short and descriptive.
15532
+ - Keep \`<prompt>\` detailed so the generated image matches the request.
15533
+ - You can include normal explanatory text before and after the notation.
15534
+ ${block(extraInstructions)}
15535
+ `));
15122
15536
  }
15123
15537
  }
15124
15538
  /**
@@ -18607,6 +19021,7 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
18607
19021
  systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
18608
19022
  };
18609
19023
  }
19024
+ requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
18610
19025
  // Remove comment lines (lines starting with #) from the final system message
18611
19026
  // while preserving the original content with comments in metadata
18612
19027
  const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
@@ -18615,6 +19030,54 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
18615
19030
  systemMessage: cleanedSystemMessage,
18616
19031
  };
18617
19032
  }
19033
+ /**
19034
+ * @private Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
19035
+ */
19036
+ async function applyPendingInlineKnowledgeSources(requirements, uploader) {
19037
+ var _a;
19038
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
19039
+ if (inlineSources.length === 0) {
19040
+ return requirements;
19041
+ }
19042
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
19043
+ for (const inlineSource of inlineSources) {
19044
+ const url = uploader
19045
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
19046
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
19047
+ knowledgeSources.push(url);
19048
+ }
19049
+ return {
19050
+ ...requirements,
19051
+ knowledgeSources,
19052
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
19053
+ };
19054
+ }
19055
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
19056
+ try {
19057
+ return await uploader(inlineSource);
19058
+ }
19059
+ catch (error) {
19060
+ console.error('[inline-knowledge] Failed to upload inline source', {
19061
+ filename: inlineSource.filename,
19062
+ error,
19063
+ });
19064
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
19065
+ }
19066
+ }
19067
+ function extractInlineKnowledgeSources(metadata) {
19068
+ if (!metadata) {
19069
+ return [];
19070
+ }
19071
+ const value = metadata.inlineKnowledgeSources;
19072
+ return Array.isArray(value) ? value : [];
19073
+ }
19074
+ function stripInlineKnowledgeMetadata(metadata) {
19075
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
19076
+ return metadata;
19077
+ }
19078
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
19079
+ return Object.keys(rest).length > 0 ? rest : undefined;
19080
+ }
18618
19081
  /**
18619
19082
  * Mocked security check for imported files
18620
19083
  *
@@ -19674,6 +20137,28 @@ function mapToolsToOpenAi(tools) {
19674
20137
  }));
19675
20138
  }
19676
20139
 
20140
+ /**
20141
+ * Builds a tool invocation script that injects hidden runtime context into tool args.
20142
+ *
20143
+ * @private utility of OpenAI tool execution wrappers
20144
+ */
20145
+ function buildToolInvocationScript(options) {
20146
+ const { functionName, functionArgsExpression } = options;
20147
+ return `
20148
+ const args = ${functionArgsExpression};
20149
+ const runtimeContextRaw =
20150
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
20151
+ ? undefined
20152
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
20153
+
20154
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
20155
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
20156
+ }
20157
+
20158
+ return await ${functionName}(args);
20159
+ `;
20160
+ }
20161
+
19677
20162
  /**
19678
20163
  * Parses an OpenAI error message to identify which parameter is unsupported
19679
20164
  *
@@ -20027,10 +20512,10 @@ class OpenAiCompatibleExecutionTools {
20027
20512
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
20028
20513
  functionResponse = await scriptTool.execute({
20029
20514
  scriptLanguage: 'javascript',
20030
- script: `
20031
- const args = ${functionArgs};
20032
- return await ${functionName}(args);
20033
- `,
20515
+ script: buildToolInvocationScript({
20516
+ functionName,
20517
+ functionArgsExpression: functionArgs,
20518
+ }),
20034
20519
  parameters: prompt.parameters,
20035
20520
  });
20036
20521
  }
@@ -21732,10 +22217,10 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
21732
22217
  try {
21733
22218
  return await scriptTool.execute({
21734
22219
  scriptLanguage: 'javascript',
21735
- script: `
21736
- const args = ${JSON.stringify(functionArgs)};
21737
- return await ${functionName}(args);
21738
- `,
22220
+ script: buildToolInvocationScript({
22221
+ functionName,
22222
+ functionArgsExpression: JSON.stringify(functionArgs),
22223
+ }),
21739
22224
  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 : {},
21740
22225
  });
21741
22226
  }
@@ -22188,10 +22673,10 @@ class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
22188
22673
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
22189
22674
  functionResponse = await scriptTool.execute({
22190
22675
  scriptLanguage: 'javascript',
22191
- script: `
22192
- const args = ${JSON.stringify(functionArgs)};
22193
- return await ${functionName}(args);
22194
- `,
22676
+ script: buildToolInvocationScript({
22677
+ functionName,
22678
+ functionArgsExpression: JSON.stringify(functionArgs),
22679
+ }),
22195
22680
  parameters: prompt.parameters,
22196
22681
  });
22197
22682
  if (this.options.isVerbose) {
@@ -23407,6 +23892,20 @@ async function _Agent_selfLearnTeacher(prompt, result) {
23407
23892
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
23408
23893
  */
23409
23894
 
23895
+ /**
23896
+ * Keep-alive helpers used for streaming chat responses.
23897
+ *
23898
+ * These constants coordinate the signal sent by the Agents Server streaming
23899
+ * endpoint and the parser in the SDK so we can distinguish between
23900
+ * real content and occasional pings.
23901
+ *
23902
+ * @private internal streaming helper for Promptbook chat connections
23903
+ */
23904
+ const CHAT_STREAM_KEEP_ALIVE_TOKEN = 'STREAM_KEEP_ALIVE';
23905
+ /**
23906
+ * Note: [💞] Ignore a discrepancy between file name and entity name
23907
+ */
23908
+
23410
23909
  /**
23411
23910
  * Resolve a remote META IMAGE value into an absolute URL when possible.
23412
23911
  */
@@ -23481,7 +23980,9 @@ class RemoteAgent extends Agent {
23481
23980
  static async connect(options) {
23482
23981
  var _a, _b, _c;
23483
23982
  const agentProfileUrl = `${options.agentUrl}/api/profile`;
23484
- const profileResponse = await fetch(agentProfileUrl);
23983
+ const profileResponse = await fetch(agentProfileUrl, {
23984
+ headers: attachClientVersionHeader(),
23985
+ });
23485
23986
  // <- TODO: [🐱‍🚀] What about closed-source agents?
23486
23987
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
23487
23988
  if (!profileResponse.ok) {
@@ -23582,6 +24083,7 @@ class RemoteAgent extends Agent {
23582
24083
  }
23583
24084
  const response = await fetch(`${this.agentUrl}/api/voice`, {
23584
24085
  method: 'POST',
24086
+ headers: attachClientVersionHeader(),
23585
24087
  body: formData,
23586
24088
  });
23587
24089
  if (!response.ok) {
@@ -23611,13 +24113,14 @@ class RemoteAgent extends Agent {
23611
24113
  const chatPrompt = prompt;
23612
24114
  const bookResponse = await fetch(`${this.agentUrl}/api/chat`, {
23613
24115
  method: 'POST',
23614
- headers: {
24116
+ headers: attachClientVersionHeader({
23615
24117
  'Content-Type': 'application/json',
23616
- },
24118
+ }),
23617
24119
  body: JSON.stringify({
23618
24120
  message: prompt.content,
23619
24121
  thread: chatPrompt.thread,
23620
24122
  attachments: chatPrompt.attachments,
24123
+ parameters: chatPrompt.parameters,
23621
24124
  }),
23622
24125
  });
23623
24126
  // <- TODO: [🐱‍🚀] What about closed-source agents?
@@ -23699,6 +24202,9 @@ class RemoteAgent extends Agent {
23699
24202
  const lines = textChunk.split(/\r?\n/);
23700
24203
  for (const line of lines) {
23701
24204
  const trimmedLine = line.trim();
24205
+ if (trimmedLine === CHAT_STREAM_KEEP_ALIVE_TOKEN) {
24206
+ continue;
24207
+ }
23702
24208
  let isToolCallLine = false;
23703
24209
  if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
23704
24210
  try {