@promptbook/node 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
@@ -35,7 +35,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
35
35
  * @generated
36
36
  * @see https://github.com/webgptorg/promptbook
37
37
  */
38
- const PROMPTBOOK_ENGINE_VERSION = '0.110.0';
38
+ const PROMPTBOOK_ENGINE_VERSION = '0.111.0-1';
39
39
  /**
40
40
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
41
41
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -11267,6 +11267,36 @@ function prompt(strings, ...values) {
11267
11267
  * Note: [💞] Ignore a discrepancy between file name and entity name
11268
11268
  */
11269
11269
 
11270
+ /**
11271
+ * HTTP header used by Promptbook clients to advertise their release version.
11272
+ *
11273
+ * @public exported from `@promptbook/utils`
11274
+ */
11275
+ const CLIENT_VERSION_HEADER = 'x-promptbook-client-version';
11276
+ /**
11277
+ * The latest client (engine) version that the server expects.
11278
+ *
11279
+ * @public exported from `@promptbook/utils`
11280
+ */
11281
+ const CLIENT_LATEST_VERSION = PROMPTBOOK_ENGINE_VERSION;
11282
+ /**
11283
+ * Creates a headers object that includes the client version header.
11284
+ *
11285
+ * @param headers - Optional base headers to clone.
11286
+ * @returns New headers object augmented with `CLIENT_VERSION_HEADER`.
11287
+ *
11288
+ * @public exported from `@promptbook/utils`
11289
+ */
11290
+ function attachClientVersionHeader(headers) {
11291
+ return {
11292
+ ...(headers !== null && headers !== void 0 ? headers : {}),
11293
+ [CLIENT_VERSION_HEADER]: CLIENT_LATEST_VERSION,
11294
+ };
11295
+ }
11296
+ /**
11297
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11298
+ */
11299
+
11270
11300
  /**
11271
11301
  * Detects if the code is running in a browser environment in main thread (Not in a web worker)
11272
11302
  *
@@ -14556,28 +14586,14 @@ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
14556
14586
  * Note: [💞] Ignore a discrepancy between file name and entity name
14557
14587
  */
14558
14588
 
14559
- /**
14560
- * @@@
14561
- *
14562
- * @private thing of inline knowledge
14563
- */
14589
+ /** @private The default base name for inline knowledge files when the content lacks identifying text */
14564
14590
  const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';
14565
- /**
14566
- * @@@
14567
- *
14568
- * @private thing of inline knowledge
14569
- */
14591
+ /** @private The default file extension used for inline knowledge uploads */
14570
14592
  const INLINE_KNOWLEDGE_EXTENSION = '.txt';
14571
- /**
14572
- * @@@
14573
- *
14574
- * @private thing of inline knowledge
14575
- */
14593
+ /** @private Prefix that identifies base64 data URLs */
14576
14594
  const DATA_URL_PREFIX = 'data:';
14577
14595
  /**
14578
- * @@@
14579
- *
14580
- * @private thing of inline knowledge
14596
+ * @private Retrieves the first meaningful line from the inline content.
14581
14597
  */
14582
14598
  function getFirstNonEmptyLine(content) {
14583
14599
  const lines = content.split(/\r?\n/);
@@ -14590,9 +14606,7 @@ function getFirstNonEmptyLine(content) {
14590
14606
  return null;
14591
14607
  }
14592
14608
  /**
14593
- * @@@
14594
- *
14595
- * @private thing of inline knowledge
14609
+ * @private Determines the base file name by normalizing the first non-empty line.
14596
14610
  */
14597
14611
  function deriveBaseFilename(content) {
14598
14612
  const firstLine = getFirstNonEmptyLine(content);
@@ -14603,22 +14617,18 @@ function deriveBaseFilename(content) {
14603
14617
  return normalized || INLINE_KNOWLEDGE_BASE_NAME;
14604
14618
  }
14605
14619
  /**
14606
- * Creates a data URL that represents the inline knowledge content as a text file.
14607
- *
14608
- * @private thing of inline knowledge
14620
+ * @private Converts inline knowledge into the internal metadata form used for uploads.
14609
14621
  */
14610
14622
  function createInlineKnowledgeSourceFile(content) {
14611
14623
  const trimmedContent = content.trim();
14612
14624
  const baseName = deriveBaseFilename(trimmedContent);
14613
14625
  const filename = `${baseName}${INLINE_KNOWLEDGE_EXTENSION}`;
14614
14626
  const mimeType = 'text/plain';
14615
- const base64 = Buffer.from(trimmedContent, 'utf-8').toString('base64');
14616
- const encodedFilename = encodeURIComponent(filename);
14617
- const url = `${DATA_URL_PREFIX}${mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
14627
+ const buffer = Buffer.from(trimmedContent, 'utf-8');
14618
14628
  return {
14619
14629
  filename,
14620
14630
  mimeType,
14621
- url,
14631
+ buffer,
14622
14632
  };
14623
14633
  }
14624
14634
  /**
@@ -14629,10 +14639,18 @@ function createInlineKnowledgeSourceFile(content) {
14629
14639
  function isDataUrlKnowledgeSource(source) {
14630
14640
  return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);
14631
14641
  }
14642
+ /**
14643
+ * @private Converts a stored inline knowledge file into a data URL for backwards compatibility.
14644
+ */
14645
+ function inlineKnowledgeSourceToDataUrl(source) {
14646
+ const base64 = source.buffer.toString('base64');
14647
+ const encodedFilename = encodeURIComponent(source.filename);
14648
+ return `${DATA_URL_PREFIX}${source.mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
14649
+ }
14632
14650
  /**
14633
14651
  * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.
14634
14652
  *
14635
- * @private thing of inline knowledge
14653
+ * @private utility of inline knowledge processing
14636
14654
  */
14637
14655
  function parseDataUrlKnowledgeSource(source) {
14638
14656
  if (!isDataUrlKnowledgeSource(source)) {
@@ -14765,6 +14783,7 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
14765
14783
  `);
14766
14784
  }
14767
14785
  applyToAgentModelRequirements(requirements, content) {
14786
+ var _a;
14768
14787
  const trimmedContent = content.trim();
14769
14788
  if (!trimmedContent) {
14770
14789
  return requirements;
@@ -14785,9 +14804,13 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
14785
14804
  }
14786
14805
  else {
14787
14806
  const inlineSource = createInlineKnowledgeSourceFile(trimmedContent);
14807
+ const existingInlineSources = (((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.inlineKnowledgeSources) || []).slice();
14788
14808
  const updatedRequirements = {
14789
14809
  ...requirements,
14790
- knowledgeSources: [...(requirements.knowledgeSources || []), inlineSource.url],
14810
+ _metadata: {
14811
+ ...requirements._metadata,
14812
+ inlineKnowledgeSources: [...existingInlineSources, inlineSource],
14813
+ },
14791
14814
  };
14792
14815
  const knowledgeInfo = `Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`;
14793
14816
  return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
@@ -14869,6 +14892,237 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
14869
14892
  * Note: [💞] Ignore a discrepancy between file name and entity name
14870
14893
  */
14871
14894
 
14895
+ /**
14896
+ * @@@
14897
+ *
14898
+ * @private utility for commitments
14899
+ */
14900
+ function formatOptionalInstructionBlock(label, content) {
14901
+ const trimmedContent = spaceTrim$1(content);
14902
+ if (!trimmedContent) {
14903
+ return '';
14904
+ }
14905
+ return spaceTrim$1((block) => `
14906
+ - ${label}:
14907
+ ${block(trimmedContent
14908
+ .split(/\r?\n/)
14909
+ .map((line) => `- ${line}`)
14910
+ .join('\n'))}
14911
+ `);
14912
+ }
14913
+
14914
+ /**
14915
+ * Prompt parameter key used to pass hidden runtime context to tool execution.
14916
+ *
14917
+ * @private internal runtime wiring for commitment tools
14918
+ */
14919
+ const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
14920
+ /**
14921
+ * Hidden argument key used to pass runtime context into individual tool calls.
14922
+ *
14923
+ * @private internal runtime wiring for commitment tools
14924
+ */
14925
+ const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
14926
+ /**
14927
+ * Parses unknown runtime context payload into a normalized object.
14928
+ *
14929
+ * @private internal runtime wiring for commitment tools
14930
+ */
14931
+ function parseToolRuntimeContext(rawValue) {
14932
+ if (!rawValue) {
14933
+ return null;
14934
+ }
14935
+ let parsed = rawValue;
14936
+ if (typeof rawValue === 'string') {
14937
+ try {
14938
+ parsed = JSON.parse(rawValue);
14939
+ }
14940
+ catch (_a) {
14941
+ return null;
14942
+ }
14943
+ }
14944
+ if (!parsed || typeof parsed !== 'object') {
14945
+ return null;
14946
+ }
14947
+ return parsed;
14948
+ }
14949
+ /**
14950
+ * Reads runtime context attached to tool call arguments.
14951
+ *
14952
+ * @private internal runtime wiring for commitment tools
14953
+ */
14954
+ function readToolRuntimeContextFromToolArgs(args) {
14955
+ return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
14956
+ }
14957
+ /**
14958
+ * Serializes runtime context for prompt parameters.
14959
+ *
14960
+ * @private internal runtime wiring for commitment tools
14961
+ */
14962
+ function serializeToolRuntimeContext(context) {
14963
+ return JSON.stringify(context);
14964
+ }
14965
+ /**
14966
+ * Note: [💞] Ignore a discrepancy between file name and entity name
14967
+ */
14968
+
14969
+ /**
14970
+ * Tool name used to retrieve persisted user memory.
14971
+ *
14972
+ * @private internal MEMORY commitment constant
14973
+ */
14974
+ const RETRIEVE_USER_MEMORY_TOOL_NAME = 'retrieve_user_memory';
14975
+ /**
14976
+ * Tool name used to store persisted user memory.
14977
+ *
14978
+ * @private internal MEMORY commitment constant
14979
+ */
14980
+ const STORE_USER_MEMORY_TOOL_NAME = 'store_user_memory';
14981
+ const UPDATE_USER_MEMORY_TOOL_NAME = 'update_user_memory';
14982
+ const DELETE_USER_MEMORY_TOOL_NAME = 'delete_user_memory';
14983
+ /**
14984
+ * Resolves runtime context from hidden tool arguments.
14985
+ *
14986
+ * @private utility of MEMORY commitment
14987
+ */
14988
+ function resolveMemoryRuntimeContext(args) {
14989
+ const runtimeContext = readToolRuntimeContextFromToolArgs(args);
14990
+ const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
14991
+ return {
14992
+ enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
14993
+ userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
14994
+ username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
14995
+ agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
14996
+ agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
14997
+ isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
14998
+ };
14999
+ }
15000
+ /**
15001
+ * Builds a disabled memory-tool response payload.
15002
+ *
15003
+ * @private utility of MEMORY commitment
15004
+ */
15005
+ function createDisabledMemoryResult(action, message) {
15006
+ if (action === 'retrieve') {
15007
+ return {
15008
+ action,
15009
+ status: 'disabled',
15010
+ memories: [],
15011
+ message,
15012
+ };
15013
+ }
15014
+ if (action === 'store') {
15015
+ return {
15016
+ action,
15017
+ status: 'disabled',
15018
+ message,
15019
+ };
15020
+ }
15021
+ if (action === 'update') {
15022
+ return {
15023
+ action,
15024
+ status: 'disabled',
15025
+ message,
15026
+ };
15027
+ }
15028
+ if (action === 'delete') {
15029
+ return {
15030
+ action,
15031
+ status: 'disabled',
15032
+ message,
15033
+ };
15034
+ }
15035
+ throw new Error(`Unsupported memory tool action: ${action}`);
15036
+ }
15037
+ /**
15038
+ * Gets the runtime adapter and returns a disabled result when unavailable.
15039
+ *
15040
+ * @private utility of MEMORY commitment
15041
+ */
15042
+ function getRuntimeAdapterOrDisabledResult(action, runtimeContext) {
15043
+ if (!runtimeContext.enabled || runtimeContext.isTeamConversation) {
15044
+ return {
15045
+ adapter: null,
15046
+ disabledResult: createDisabledMemoryResult(action, runtimeContext.isTeamConversation
15047
+ ? 'Memory is disabled for TEAM conversations.'
15048
+ : 'Memory is disabled for unauthenticated users.'),
15049
+ };
15050
+ }
15051
+ {
15052
+ return {
15053
+ adapter: null,
15054
+ disabledResult: createDisabledMemoryResult(action, 'Memory runtime is not available in this environment.'),
15055
+ };
15056
+ }
15057
+ }
15058
+ /**
15059
+ * Parses retrieve memory arguments.
15060
+ *
15061
+ * @private utility of MEMORY commitment
15062
+ */
15063
+ function parseRetrieveMemoryArgs(args) {
15064
+ const query = typeof args.query === 'string' ? args.query.trim() : undefined;
15065
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
15066
+ return {
15067
+ query: query && query.length > 0 ? query : undefined,
15068
+ limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
15069
+ };
15070
+ }
15071
+ /**
15072
+ * Parses store memory arguments.
15073
+ *
15074
+ * @private utility of MEMORY commitment
15075
+ */
15076
+ function parseStoreMemoryArgs(args) {
15077
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
15078
+ if (!content) {
15079
+ throw new Error('Memory content is required.');
15080
+ }
15081
+ return {
15082
+ content,
15083
+ isGlobal: args.isGlobal === true,
15084
+ };
15085
+ }
15086
+ /**
15087
+ * Parses a memory identifier argument shared across MEMORY tools.
15088
+ *
15089
+ * @private utility of MEMORY commitment
15090
+ */
15091
+ function parseMemoryIdArg(value) {
15092
+ const memoryId = typeof value === 'string' ? value.trim() : '';
15093
+ if (!memoryId) {
15094
+ throw new Error('Memory id is required.');
15095
+ }
15096
+ return memoryId;
15097
+ }
15098
+ /**
15099
+ * Parses update memory arguments.
15100
+ *
15101
+ * @private utility of MEMORY commitment
15102
+ */
15103
+ function parseUpdateMemoryArgs(args) {
15104
+ const memoryId = parseMemoryIdArg(args.memoryId);
15105
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
15106
+ if (!content) {
15107
+ throw new Error('Memory content is required.');
15108
+ }
15109
+ const isGlobal = typeof args.isGlobal === 'boolean' ? args.isGlobal : undefined;
15110
+ return {
15111
+ memoryId,
15112
+ content,
15113
+ isGlobal,
15114
+ };
15115
+ }
15116
+ /**
15117
+ * Parses delete memory arguments.
15118
+ *
15119
+ * @private utility of MEMORY commitment
15120
+ */
15121
+ function parseDeleteMemoryArgs(args) {
15122
+ return {
15123
+ memoryId: parseMemoryIdArg(args.memoryId),
15124
+ };
15125
+ }
14872
15126
  /**
14873
15127
  * MEMORY commitment definition
14874
15128
  *
@@ -14890,6 +15144,9 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
14890
15144
  constructor(type = 'MEMORY') {
14891
15145
  super(type);
14892
15146
  }
15147
+ get requiresContent() {
15148
+ return false;
15149
+ }
14893
15150
  /**
14894
15151
  * Short one-line description of MEMORY.
14895
15152
  */
@@ -14909,21 +15166,14 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
14909
15166
  return spaceTrim$1(`
14910
15167
  # ${this.type}
14911
15168
 
14912
- 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.
15169
+ Enables persistent user memory for the current agent. The memory is stored by the runtime and can be retrieved in future conversations.
14913
15170
 
14914
15171
  ## Key aspects
14915
15172
 
14916
- - Both terms work identically and can be used interchangeably.
14917
- - Focuses on user-specific information and interaction history.
14918
- - Helps personalize responses based on past interactions.
14919
- - Maintains continuity across conversations.
14920
-
14921
- ## Differences from KNOWLEDGE
14922
-
14923
- - \`KNOWLEDGE\` is for domain expertise and factual information
14924
- - \`MEMORY\` is for user-specific context and preferences
14925
- - \`MEMORY\` creates more personalized interactions
14926
- - \`MEMORY\` often includes temporal or preference-based information
15173
+ - Both \`MEMORY\` and \`MEMORIES\` work identically.
15174
+ - Stores user-specific details through runtime tools.
15175
+ - Retrieves relevant memories for personalized responses.
15176
+ - Supports optional extra instructions in the commitment content.
14927
15177
 
14928
15178
  ## Examples
14929
15179
 
@@ -14931,10 +15181,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
14931
15181
  Personal Assistant
14932
15182
 
14933
15183
  PERSONA You are a personal productivity assistant
14934
- MEMORY User is a software developer working in JavaScript/React
14935
- MEMORY User prefers morning work sessions and afternoon meetings
14936
- MEMORY Previously helped with project planning for mobile apps
14937
- MEMORY User timezone: UTC-8 (Pacific Time)
15184
+ MEMORY Remember user projects and long-term preferences.
14938
15185
  GOAL Help optimize daily productivity and workflow
14939
15186
  \`\`\`
14940
15187
 
@@ -14942,10 +15189,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
14942
15189
  Learning Companion
14943
15190
 
14944
15191
  PERSONA You are an educational companion for programming students
14945
- MEMORY Student is learning Python as their first programming language
14946
- MEMORY Previous topics covered: variables, loops, functions
14947
- MEMORY Student learns best with practical examples and exercises
14948
- MEMORY Last session: working on list comprehensions
15192
+ MEMORY Remember only the student's learning progress and preferred study style.
14949
15193
  GOAL Provide progressive learning experiences tailored to student's pace
14950
15194
  \`\`\`
14951
15195
 
@@ -14953,23 +15197,245 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
14953
15197
  Customer Support Agent
14954
15198
 
14955
15199
  PERSONA You are a customer support representative
14956
- MEMORY Customer has premium subscription since 2023
14957
- MEMORY Previous issue: billing question resolved last month
14958
- MEMORY Customer prefers email communication over phone calls
14959
- MEMORY Account shows frequent use of advanced features
15200
+ MEMORY Remember only important support history and communication preferences.
14960
15201
  GOAL Provide personalized support based on customer history
14961
15202
  \`\`\`
14962
15203
  `);
14963
15204
  }
14964
15205
  applyToAgentModelRequirements(requirements, content) {
14965
- const trimmedContent = content.trim();
14966
- if (!trimmedContent) {
14967
- return requirements;
15206
+ const extraInstructions = formatOptionalInstructionBlock('Memory instructions', content);
15207
+ const existingTools = requirements.tools || [];
15208
+ const tools = [...existingTools];
15209
+ if (!tools.some((tool) => tool.name === RETRIEVE_USER_MEMORY_TOOL_NAME)) {
15210
+ tools.push({
15211
+ name: RETRIEVE_USER_MEMORY_TOOL_NAME,
15212
+ description: spaceTrim$1(`
15213
+ Retrieve previously stored user memories relevant to the current conversation.
15214
+ Use this before responding when user context can improve the answer.
15215
+ `),
15216
+ parameters: {
15217
+ type: 'object',
15218
+ properties: {
15219
+ query: {
15220
+ type: 'string',
15221
+ description: 'Optional query used to filter relevant memories.',
15222
+ },
15223
+ limit: {
15224
+ type: 'integer',
15225
+ description: 'Optional maximum number of memories to return (default 5, max 20).',
15226
+ },
15227
+ },
15228
+ },
15229
+ });
15230
+ }
15231
+ if (!tools.some((tool) => tool.name === STORE_USER_MEMORY_TOOL_NAME)) {
15232
+ tools.push({
15233
+ name: STORE_USER_MEMORY_TOOL_NAME,
15234
+ description: spaceTrim$1(`
15235
+ Store a durable user memory that should be remembered in future conversations.
15236
+ Store only stable and useful user-specific facts or preferences.
15237
+ `),
15238
+ parameters: {
15239
+ type: 'object',
15240
+ properties: {
15241
+ content: {
15242
+ type: 'string',
15243
+ description: 'Memory text to store.',
15244
+ },
15245
+ isGlobal: {
15246
+ type: 'boolean',
15247
+ description: 'Set true to make this memory global across all user agents.',
15248
+ },
15249
+ },
15250
+ required: ['content'],
15251
+ },
15252
+ });
15253
+ }
15254
+ if (!tools.some((tool) => tool.name === UPDATE_USER_MEMORY_TOOL_NAME)) {
15255
+ tools.push({
15256
+ name: UPDATE_USER_MEMORY_TOOL_NAME,
15257
+ description: spaceTrim$1(`
15258
+ Update an existing user memory after retrieving it, so the stored fact stays accurate.
15259
+ Always pass the memory id you retrieved along with the new content.
15260
+ `),
15261
+ parameters: {
15262
+ type: 'object',
15263
+ properties: {
15264
+ memoryId: {
15265
+ type: 'string',
15266
+ description: 'Unique identifier of the memory entry to update.',
15267
+ },
15268
+ content: {
15269
+ type: 'string',
15270
+ description: 'Updated memory text.',
15271
+ },
15272
+ isGlobal: {
15273
+ type: 'boolean',
15274
+ description: 'Set true to keep the fact global; omit or false to keep it agent-scoped.',
15275
+ },
15276
+ },
15277
+ required: ['memoryId', 'content'],
15278
+ },
15279
+ });
15280
+ }
15281
+ if (!tools.some((tool) => tool.name === DELETE_USER_MEMORY_TOOL_NAME)) {
15282
+ tools.push({
15283
+ name: DELETE_USER_MEMORY_TOOL_NAME,
15284
+ description: spaceTrim$1(`
15285
+ Delete a user memory that is no longer relevant. Deletions are soft so the record is hidden from future queries.
15286
+ `),
15287
+ parameters: {
15288
+ type: 'object',
15289
+ properties: {
15290
+ memoryId: {
15291
+ type: 'string',
15292
+ description: 'Unique identifier of the memory entry to delete.',
15293
+ },
15294
+ },
15295
+ required: ['memoryId'],
15296
+ },
15297
+ });
14968
15298
  }
14969
- // Create memory section for system message
14970
- const memorySection = `Memory: ${trimmedContent}`;
14971
- // Memory information is contextual and should be included in the system message
14972
- return this.appendToSystemMessage(requirements, memorySection, '\n\n');
15299
+ return this.appendToSystemMessage({
15300
+ ...requirements,
15301
+ tools,
15302
+ _metadata: {
15303
+ ...requirements._metadata,
15304
+ useMemory: content || true,
15305
+ },
15306
+ }, spaceTrim$1((block) => `
15307
+ Memory:
15308
+ - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
15309
+ - You can use persistent user memory tools.
15310
+ - Use "${RETRIEVE_USER_MEMORY_TOOL_NAME}" to load relevant memory before answering.
15311
+ - Use "${STORE_USER_MEMORY_TOOL_NAME}" to save stable user-specific facts that improve future help.
15312
+ - Use "${UPDATE_USER_MEMORY_TOOL_NAME}" to refresh an existing memory when the content changes.
15313
+ - Use "${DELETE_USER_MEMORY_TOOL_NAME}" to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
15314
+ - Store concise memory items and avoid duplicates.
15315
+ - Never claim memory was saved or loaded unless the tool confirms it.
15316
+ ${block(extraInstructions)}
15317
+ `));
15318
+ }
15319
+ /**
15320
+ * Gets human-readable titles for MEMORY tool functions.
15321
+ */
15322
+ getToolTitles() {
15323
+ return {
15324
+ [RETRIEVE_USER_MEMORY_TOOL_NAME]: 'User memory',
15325
+ [STORE_USER_MEMORY_TOOL_NAME]: 'Store user memory',
15326
+ [UPDATE_USER_MEMORY_TOOL_NAME]: 'Update user memory',
15327
+ [DELETE_USER_MEMORY_TOOL_NAME]: 'Delete user memory',
15328
+ };
15329
+ }
15330
+ /**
15331
+ * Gets MEMORY tool function implementations.
15332
+ */
15333
+ getToolFunctions() {
15334
+ return {
15335
+ async [RETRIEVE_USER_MEMORY_TOOL_NAME](args) {
15336
+ const runtimeContext = resolveMemoryRuntimeContext(args);
15337
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
15338
+ if (!adapter || disabledResult) {
15339
+ return JSON.stringify(disabledResult);
15340
+ }
15341
+ const parsedArgs = parseRetrieveMemoryArgs(args);
15342
+ try {
15343
+ const memories = await adapter.retrieveMemories(parsedArgs, runtimeContext);
15344
+ const result = {
15345
+ action: 'retrieve',
15346
+ status: 'ok',
15347
+ query: parsedArgs.query,
15348
+ memories,
15349
+ };
15350
+ return JSON.stringify(result);
15351
+ }
15352
+ catch (error) {
15353
+ const result = {
15354
+ action: 'retrieve',
15355
+ status: 'error',
15356
+ query: parsedArgs.query,
15357
+ memories: [],
15358
+ message: error instanceof Error ? error.message : String(error),
15359
+ };
15360
+ return JSON.stringify(result);
15361
+ }
15362
+ },
15363
+ async [STORE_USER_MEMORY_TOOL_NAME](args) {
15364
+ const runtimeContext = resolveMemoryRuntimeContext(args);
15365
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('store', runtimeContext);
15366
+ if (!adapter || disabledResult) {
15367
+ return JSON.stringify(disabledResult);
15368
+ }
15369
+ try {
15370
+ const parsedArgs = parseStoreMemoryArgs(args);
15371
+ const memory = await adapter.storeMemory(parsedArgs, runtimeContext);
15372
+ const result = {
15373
+ action: 'store',
15374
+ status: 'stored',
15375
+ memory,
15376
+ };
15377
+ return JSON.stringify(result);
15378
+ }
15379
+ catch (error) {
15380
+ const result = {
15381
+ action: 'store',
15382
+ status: 'error',
15383
+ message: error instanceof Error ? error.message : String(error),
15384
+ };
15385
+ return JSON.stringify(result);
15386
+ }
15387
+ },
15388
+ async [UPDATE_USER_MEMORY_TOOL_NAME](args) {
15389
+ const runtimeContext = resolveMemoryRuntimeContext(args);
15390
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('update', runtimeContext);
15391
+ if (!adapter || disabledResult) {
15392
+ return JSON.stringify(disabledResult);
15393
+ }
15394
+ try {
15395
+ const parsedArgs = parseUpdateMemoryArgs(args);
15396
+ const memory = await adapter.updateMemory(parsedArgs, runtimeContext);
15397
+ const result = {
15398
+ action: 'update',
15399
+ status: 'updated',
15400
+ memory,
15401
+ };
15402
+ return JSON.stringify(result);
15403
+ }
15404
+ catch (error) {
15405
+ const result = {
15406
+ action: 'update',
15407
+ status: 'error',
15408
+ message: error instanceof Error ? error.message : String(error),
15409
+ };
15410
+ return JSON.stringify(result);
15411
+ }
15412
+ },
15413
+ async [DELETE_USER_MEMORY_TOOL_NAME](args) {
15414
+ const runtimeContext = resolveMemoryRuntimeContext(args);
15415
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('delete', runtimeContext);
15416
+ if (!adapter || disabledResult) {
15417
+ return JSON.stringify(disabledResult);
15418
+ }
15419
+ try {
15420
+ const parsedArgs = parseDeleteMemoryArgs(args);
15421
+ const deleted = await adapter.deleteMemory(parsedArgs, runtimeContext);
15422
+ const result = {
15423
+ action: 'delete',
15424
+ status: 'deleted',
15425
+ memoryId: deleted.id,
15426
+ };
15427
+ return JSON.stringify(result);
15428
+ }
15429
+ catch (error) {
15430
+ const result = {
15431
+ action: 'delete',
15432
+ status: 'error',
15433
+ message: error instanceof Error ? error.message : String(error),
15434
+ };
15435
+ return JSON.stringify(result);
15436
+ }
15437
+ },
15438
+ };
14973
15439
  }
14974
15440
  }
14975
15441
  /**
@@ -17082,14 +17548,30 @@ function buildTeammateRequest(message, context) {
17082
17548
  /**
17083
17549
  * Builds a minimal chat prompt for teammate calls.
17084
17550
  */
17085
- function buildTeammatePrompt(request) {
17551
+ function buildTeammatePrompt(request, runtimeContext) {
17086
17552
  return {
17087
17553
  title: 'Teammate consultation',
17088
17554
  modelRequirements: {
17089
17555
  modelVariant: 'CHAT',
17090
17556
  },
17091
17557
  content: request,
17092
- parameters: {},
17558
+ parameters: {
17559
+ [TOOL_RUNTIME_CONTEXT_PARAMETER]: serializeToolRuntimeContext(runtimeContext),
17560
+ },
17561
+ };
17562
+ }
17563
+ /**
17564
+ * Creates teammate runtime context and marks conversation as team-only memory-disabled.
17565
+ */
17566
+ function createTeamConversationRuntimeContext(value) {
17567
+ const runtimeContext = parseToolRuntimeContext(value) || {};
17568
+ return {
17569
+ ...runtimeContext,
17570
+ memory: {
17571
+ ...(runtimeContext.memory || {}),
17572
+ enabled: false,
17573
+ isTeamConversation: true,
17574
+ },
17093
17575
  };
17094
17576
  }
17095
17577
  /**
@@ -17133,7 +17615,7 @@ function createTeamToolFunction(entry) {
17133
17615
  let toolCalls;
17134
17616
  try {
17135
17617
  const remoteAgent = await getRemoteTeammateAgent(entry.teammate.url);
17136
- const prompt = buildTeammatePrompt(request);
17618
+ const prompt = buildTeammatePrompt(request, createTeamConversationRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]));
17137
17619
  const teammateResult = await remoteAgent.callChatModel(prompt);
17138
17620
  response = teammateResult.content || '';
17139
17621
  toolCalls =
@@ -17683,25 +18165,6 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
17683
18165
  * Note: [💞] Ignore a discrepancy between file name and entity name
17684
18166
  */
17685
18167
 
17686
- /**
17687
- * @@@
17688
- *
17689
- * @private utility for commitments
17690
- */
17691
- function formatOptionalInstructionBlock(label, content) {
17692
- const trimmedContent = spaceTrim$1(content);
17693
- if (!trimmedContent) {
17694
- return '';
17695
- }
17696
- return spaceTrim$1((block) => `
17697
- - ${label}:
17698
- ${block(trimmedContent
17699
- .split(/\r?\n/)
17700
- .map((line) => `- ${line}`)
17701
- .join('\n'))}
17702
- `);
17703
- }
17704
-
17705
18168
  /**
17706
18169
  * Client-side safe wrapper for sending emails.
17707
18170
  *
@@ -17895,8 +18358,8 @@ class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
17895
18358
  /**
17896
18359
  * USE IMAGE GENERATOR commitment definition
17897
18360
  *
17898
- * The `USE IMAGE GENERATOR` commitment indicates that the agent should utilize an image generation tool
17899
- * to create images based on text prompts.
18361
+ * The `USE IMAGE GENERATOR` commitment indicates that the agent can output
18362
+ * markdown placeholders for UI-driven image generation.
17900
18363
  *
17901
18364
  * Example usage in agent source:
17902
18365
  *
@@ -17911,11 +18374,14 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
17911
18374
  constructor(type = 'USE IMAGE GENERATOR') {
17912
18375
  super(type, ['USE IMAGE GENERATION', 'IMAGE GENERATOR', 'IMAGE GENERATION', 'USE IMAGE']);
17913
18376
  }
18377
+ get requiresContent() {
18378
+ return false;
18379
+ }
17914
18380
  /**
17915
18381
  * Short one-line description of USE IMAGE GENERATOR.
17916
18382
  */
17917
18383
  get description() {
17918
- return 'Enable the agent to use an image generation tool for creating images from text prompts.';
18384
+ return 'Enable the agent to output markdown image placeholders that the UI turns into generated images.';
17919
18385
  }
17920
18386
  /**
17921
18387
  * Icon for this commitment.
@@ -17930,21 +18396,21 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
17930
18396
  return spaceTrim$1(`
17931
18397
  # USE IMAGE GENERATOR
17932
18398
 
17933
- Enables the agent to use an image generation tool to create images based on text prompts.
18399
+ Enables the agent to output markdown image placeholders that trigger image generation in the user interface.
17934
18400
 
17935
18401
  ## Key aspects
17936
18402
 
17937
18403
  - The content following \`USE IMAGE GENERATOR\` is an arbitrary text that the agent should know (e.g. style instructions or safety guidelines).
17938
- - The actual image generation is handled by the agent runtime using LLM execution tools.
17939
- - Allows the agent to generate visual content based on user requests.
17940
- - Returns the URL of the generated image.
18404
+ - The agent does **not** call an image-generation tool directly.
18405
+ - The agent inserts markdown notation: \`![alt](?image-prompt=...)\`.
18406
+ - The user interface detects the notation and generates the image asynchronously.
17941
18407
 
17942
18408
  ## Examples
17943
18409
 
17944
18410
  \`\`\`book
17945
18411
  Visual Artist
17946
18412
 
17947
- PERSONA You are a creative visual artist who can generate images.
18413
+ PERSONA You are a creative visual artist.
17948
18414
  USE IMAGE GENERATOR
17949
18415
  RULE Always describe the generated image to the user.
17950
18416
  \`\`\`
@@ -17954,80 +18420,28 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
17954
18420
 
17955
18421
  PERSONA You are an interior designer who helps users visualize their space.
17956
18422
  USE IMAGE GENERATOR Professional interior design renders.
17957
- ACTION Generate a preview of the designed room.
18423
+ ACTION Add one generated image placeholder whenever a user asks for a visual.
17958
18424
  \`\`\`
17959
18425
  `);
17960
18426
  }
17961
18427
  applyToAgentModelRequirements(requirements, content) {
17962
- // Get existing tools array or create new one
17963
- const existingTools = requirements.tools || [];
17964
- // Add 'generate_image' to tools if not already present
17965
- const updatedTools = existingTools.some((tool) => tool.name === 'generate_image')
17966
- ? existingTools
17967
- : [
17968
- ...existingTools,
17969
- {
17970
- name: 'generate_image',
17971
- description: spaceTrim$1(`
17972
- Generate an image from a text prompt.
17973
- Use this tool when the user asks to create, draw, or generate an image.
17974
- ${!content ? '' : `Style instructions / guidelines: ${content}`}
17975
- `),
17976
- parameters: {
17977
- type: 'object',
17978
- properties: {
17979
- prompt: {
17980
- type: 'string',
17981
- description: 'The detailed description of the image to generate',
17982
- },
17983
- },
17984
- required: ['prompt'],
17985
- },
17986
- },
17987
- ];
17988
- // Return requirements with updated tools and metadata
18428
+ const extraInstructions = formatOptionalInstructionBlock('Image instructions', content);
17989
18429
  return this.appendToSystemMessage({
17990
18430
  ...requirements,
17991
- tools: updatedTools,
17992
18431
  _metadata: {
17993
18432
  ...requirements._metadata,
17994
18433
  useImageGenerator: content || true,
17995
18434
  },
17996
- }, spaceTrim$1(`
17997
- You have access to an image generator. Use it to create images based on user requests.
17998
- When you generate an image, you will receive a URL of the generated image.
17999
- `));
18000
- }
18001
- /**
18002
- * Gets human-readable titles for tool functions provided by this commitment.
18003
- */
18004
- getToolTitles() {
18005
- return {
18006
- generate_image: 'Generate image',
18007
- };
18008
- }
18009
- /**
18010
- * Gets the `generate_image` tool function implementation.
18011
- */
18012
- getToolFunctions() {
18013
- return {
18014
- async generate_image(args, ...extra) {
18015
- console.log('!!!! [Tool] generate_image called', { args });
18016
- const { prompt } = args;
18017
- if (!prompt) {
18018
- throw new Error('Image prompt is required');
18019
- }
18020
- const { llmTools } = extra[0] || {};
18021
- if (!llmTools || !llmTools.callImageGenerationModel) {
18022
- throw new Error('Image generation is not supported by the current model provider');
18023
- }
18024
- const result = await llmTools.callImageGenerationModel({
18025
- content: prompt,
18026
- modelName: 'dall-e-3', // Defaulting to dall-e-3, but this could be configurable
18027
- });
18028
- return result.content;
18029
- },
18030
- };
18435
+ }, spaceTrim$1((block) => `
18436
+ Image generation:
18437
+ - You do not generate images directly and you do not call any image tool.
18438
+ - When the user asks for an image, include markdown notation in your message:
18439
+ \`![<alt text>](?image-prompt=<prompt>)\`
18440
+ - Keep \`<alt text>\` short and descriptive.
18441
+ - Keep \`<prompt>\` detailed so the generated image matches the request.
18442
+ - You can include normal explanatory text before and after the notation.
18443
+ ${block(extraInstructions)}
18444
+ `));
18031
18445
  }
18032
18446
  }
18033
18447
  /**
@@ -21503,6 +21917,7 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
21503
21917
  systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
21504
21918
  };
21505
21919
  }
21920
+ requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
21506
21921
  // Remove comment lines (lines starting with #) from the final system message
21507
21922
  // while preserving the original content with comments in metadata
21508
21923
  const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
@@ -21511,6 +21926,54 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
21511
21926
  systemMessage: cleanedSystemMessage,
21512
21927
  };
21513
21928
  }
21929
+ /**
21930
+ * @private Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
21931
+ */
21932
+ async function applyPendingInlineKnowledgeSources(requirements, uploader) {
21933
+ var _a;
21934
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
21935
+ if (inlineSources.length === 0) {
21936
+ return requirements;
21937
+ }
21938
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
21939
+ for (const inlineSource of inlineSources) {
21940
+ const url = uploader
21941
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
21942
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
21943
+ knowledgeSources.push(url);
21944
+ }
21945
+ return {
21946
+ ...requirements,
21947
+ knowledgeSources,
21948
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
21949
+ };
21950
+ }
21951
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
21952
+ try {
21953
+ return await uploader(inlineSource);
21954
+ }
21955
+ catch (error) {
21956
+ console.error('[inline-knowledge] Failed to upload inline source', {
21957
+ filename: inlineSource.filename,
21958
+ error,
21959
+ });
21960
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
21961
+ }
21962
+ }
21963
+ function extractInlineKnowledgeSources(metadata) {
21964
+ if (!metadata) {
21965
+ return [];
21966
+ }
21967
+ const value = metadata.inlineKnowledgeSources;
21968
+ return Array.isArray(value) ? value : [];
21969
+ }
21970
+ function stripInlineKnowledgeMetadata(metadata) {
21971
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
21972
+ return metadata;
21973
+ }
21974
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
21975
+ return Object.keys(rest).length > 0 ? rest : undefined;
21976
+ }
21514
21977
  /**
21515
21978
  * Mocked security check for imported files
21516
21979
  *
@@ -22570,6 +23033,28 @@ function mapToolsToOpenAi(tools) {
22570
23033
  }));
22571
23034
  }
22572
23035
 
23036
+ /**
23037
+ * Builds a tool invocation script that injects hidden runtime context into tool args.
23038
+ *
23039
+ * @private utility of OpenAI tool execution wrappers
23040
+ */
23041
+ function buildToolInvocationScript(options) {
23042
+ const { functionName, functionArgsExpression } = options;
23043
+ return `
23044
+ const args = ${functionArgsExpression};
23045
+ const runtimeContextRaw =
23046
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
23047
+ ? undefined
23048
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
23049
+
23050
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
23051
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
23052
+ }
23053
+
23054
+ return await ${functionName}(args);
23055
+ `;
23056
+ }
23057
+
22573
23058
  /**
22574
23059
  * Parses an OpenAI error message to identify which parameter is unsupported
22575
23060
  *
@@ -22923,10 +23408,10 @@ class OpenAiCompatibleExecutionTools {
22923
23408
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
22924
23409
  functionResponse = await scriptTool.execute({
22925
23410
  scriptLanguage: 'javascript',
22926
- script: `
22927
- const args = ${functionArgs};
22928
- return await ${functionName}(args);
22929
- `,
23411
+ script: buildToolInvocationScript({
23412
+ functionName,
23413
+ functionArgsExpression: functionArgs,
23414
+ }),
22930
23415
  parameters: prompt.parameters,
22931
23416
  });
22932
23417
  }
@@ -24628,10 +25113,10 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
24628
25113
  try {
24629
25114
  return await scriptTool.execute({
24630
25115
  scriptLanguage: 'javascript',
24631
- script: `
24632
- const args = ${JSON.stringify(functionArgs)};
24633
- return await ${functionName}(args);
24634
- `,
25116
+ script: buildToolInvocationScript({
25117
+ functionName,
25118
+ functionArgsExpression: JSON.stringify(functionArgs),
25119
+ }),
24635
25120
  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 : {},
24636
25121
  });
24637
25122
  }
@@ -25084,10 +25569,10 @@ class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
25084
25569
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
25085
25570
  functionResponse = await scriptTool.execute({
25086
25571
  scriptLanguage: 'javascript',
25087
- script: `
25088
- const args = ${JSON.stringify(functionArgs)};
25089
- return await ${functionName}(args);
25090
- `,
25572
+ script: buildToolInvocationScript({
25573
+ functionName,
25574
+ functionArgsExpression: JSON.stringify(functionArgs),
25575
+ }),
25091
25576
  parameters: prompt.parameters,
25092
25577
  });
25093
25578
  if (this.options.isVerbose) {
@@ -26303,6 +26788,20 @@ async function _Agent_selfLearnTeacher(prompt, result) {
26303
26788
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
26304
26789
  */
26305
26790
 
26791
+ /**
26792
+ * Keep-alive helpers used for streaming chat responses.
26793
+ *
26794
+ * These constants coordinate the signal sent by the Agents Server streaming
26795
+ * endpoint and the parser in the SDK so we can distinguish between
26796
+ * real content and occasional pings.
26797
+ *
26798
+ * @private internal streaming helper for Promptbook chat connections
26799
+ */
26800
+ const CHAT_STREAM_KEEP_ALIVE_TOKEN = 'STREAM_KEEP_ALIVE';
26801
+ /**
26802
+ * Note: [💞] Ignore a discrepancy between file name and entity name
26803
+ */
26804
+
26306
26805
  /**
26307
26806
  * Resolve a remote META IMAGE value into an absolute URL when possible.
26308
26807
  */
@@ -26377,7 +26876,9 @@ class RemoteAgent extends Agent {
26377
26876
  static async connect(options) {
26378
26877
  var _a, _b, _c;
26379
26878
  const agentProfileUrl = `${options.agentUrl}/api/profile`;
26380
- const profileResponse = await fetch(agentProfileUrl);
26879
+ const profileResponse = await fetch(agentProfileUrl, {
26880
+ headers: attachClientVersionHeader(),
26881
+ });
26381
26882
  // <- TODO: [🐱‍🚀] What about closed-source agents?
26382
26883
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
26383
26884
  if (!profileResponse.ok) {
@@ -26478,6 +26979,7 @@ class RemoteAgent extends Agent {
26478
26979
  }
26479
26980
  const response = await fetch(`${this.agentUrl}/api/voice`, {
26480
26981
  method: 'POST',
26982
+ headers: attachClientVersionHeader(),
26481
26983
  body: formData,
26482
26984
  });
26483
26985
  if (!response.ok) {
@@ -26507,13 +27009,14 @@ class RemoteAgent extends Agent {
26507
27009
  const chatPrompt = prompt;
26508
27010
  const bookResponse = await fetch(`${this.agentUrl}/api/chat`, {
26509
27011
  method: 'POST',
26510
- headers: {
27012
+ headers: attachClientVersionHeader({
26511
27013
  'Content-Type': 'application/json',
26512
- },
27014
+ }),
26513
27015
  body: JSON.stringify({
26514
27016
  message: prompt.content,
26515
27017
  thread: chatPrompt.thread,
26516
27018
  attachments: chatPrompt.attachments,
27019
+ parameters: chatPrompt.parameters,
26517
27020
  }),
26518
27021
  });
26519
27022
  // <- TODO: [🐱‍🚀] What about closed-source agents?
@@ -26595,6 +27098,9 @@ class RemoteAgent extends Agent {
26595
27098
  const lines = textChunk.split(/\r?\n/);
26596
27099
  for (const line of lines) {
26597
27100
  const trimmedLine = line.trim();
27101
+ if (trimmedLine === CHAT_STREAM_KEEP_ALIVE_TOKEN) {
27102
+ continue;
27103
+ }
26598
27104
  let isToolCallLine = false;
26599
27105
  if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
26600
27106
  try {