@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/umd/index.umd.js CHANGED
@@ -50,7 +50,7 @@
50
50
  * @generated
51
51
  * @see https://github.com/webgptorg/promptbook
52
52
  */
53
- const PROMPTBOOK_ENGINE_VERSION = '0.110.0';
53
+ const PROMPTBOOK_ENGINE_VERSION = '0.111.0-1';
54
54
  /**
55
55
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
56
56
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -8457,6 +8457,36 @@
8457
8457
  * Note: [💞] Ignore a discrepancy between file name and entity name
8458
8458
  */
8459
8459
 
8460
+ /**
8461
+ * HTTP header used by Promptbook clients to advertise their release version.
8462
+ *
8463
+ * @public exported from `@promptbook/utils`
8464
+ */
8465
+ const CLIENT_VERSION_HEADER = 'x-promptbook-client-version';
8466
+ /**
8467
+ * The latest client (engine) version that the server expects.
8468
+ *
8469
+ * @public exported from `@promptbook/utils`
8470
+ */
8471
+ const CLIENT_LATEST_VERSION = PROMPTBOOK_ENGINE_VERSION;
8472
+ /**
8473
+ * Creates a headers object that includes the client version header.
8474
+ *
8475
+ * @param headers - Optional base headers to clone.
8476
+ * @returns New headers object augmented with `CLIENT_VERSION_HEADER`.
8477
+ *
8478
+ * @public exported from `@promptbook/utils`
8479
+ */
8480
+ function attachClientVersionHeader(headers) {
8481
+ return {
8482
+ ...(headers !== null && headers !== void 0 ? headers : {}),
8483
+ [CLIENT_VERSION_HEADER]: CLIENT_LATEST_VERSION,
8484
+ };
8485
+ }
8486
+ /**
8487
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8488
+ */
8489
+
8460
8490
  /**
8461
8491
  * Computes SHA-256 hash of the given object
8462
8492
  *
@@ -11657,28 +11687,14 @@
11657
11687
  * Note: [💞] Ignore a discrepancy between file name and entity name
11658
11688
  */
11659
11689
 
11660
- /**
11661
- * @@@
11662
- *
11663
- * @private thing of inline knowledge
11664
- */
11690
+ /** @private The default base name for inline knowledge files when the content lacks identifying text */
11665
11691
  const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';
11666
- /**
11667
- * @@@
11668
- *
11669
- * @private thing of inline knowledge
11670
- */
11692
+ /** @private The default file extension used for inline knowledge uploads */
11671
11693
  const INLINE_KNOWLEDGE_EXTENSION = '.txt';
11672
- /**
11673
- * @@@
11674
- *
11675
- * @private thing of inline knowledge
11676
- */
11694
+ /** @private Prefix that identifies base64 data URLs */
11677
11695
  const DATA_URL_PREFIX = 'data:';
11678
11696
  /**
11679
- * @@@
11680
- *
11681
- * @private thing of inline knowledge
11697
+ * @private Retrieves the first meaningful line from the inline content.
11682
11698
  */
11683
11699
  function getFirstNonEmptyLine(content) {
11684
11700
  const lines = content.split(/\r?\n/);
@@ -11691,9 +11707,7 @@
11691
11707
  return null;
11692
11708
  }
11693
11709
  /**
11694
- * @@@
11695
- *
11696
- * @private thing of inline knowledge
11710
+ * @private Determines the base file name by normalizing the first non-empty line.
11697
11711
  */
11698
11712
  function deriveBaseFilename(content) {
11699
11713
  const firstLine = getFirstNonEmptyLine(content);
@@ -11704,22 +11718,18 @@
11704
11718
  return normalized || INLINE_KNOWLEDGE_BASE_NAME;
11705
11719
  }
11706
11720
  /**
11707
- * Creates a data URL that represents the inline knowledge content as a text file.
11708
- *
11709
- * @private thing of inline knowledge
11721
+ * @private Converts inline knowledge into the internal metadata form used for uploads.
11710
11722
  */
11711
11723
  function createInlineKnowledgeSourceFile(content) {
11712
11724
  const trimmedContent = content.trim();
11713
11725
  const baseName = deriveBaseFilename(trimmedContent);
11714
11726
  const filename = `${baseName}${INLINE_KNOWLEDGE_EXTENSION}`;
11715
11727
  const mimeType = 'text/plain';
11716
- const base64 = Buffer.from(trimmedContent, 'utf-8').toString('base64');
11717
- const encodedFilename = encodeURIComponent(filename);
11718
- const url = `${DATA_URL_PREFIX}${mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
11728
+ const buffer = Buffer.from(trimmedContent, 'utf-8');
11719
11729
  return {
11720
11730
  filename,
11721
11731
  mimeType,
11722
- url,
11732
+ buffer,
11723
11733
  };
11724
11734
  }
11725
11735
  /**
@@ -11730,10 +11740,18 @@
11730
11740
  function isDataUrlKnowledgeSource(source) {
11731
11741
  return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);
11732
11742
  }
11743
+ /**
11744
+ * @private Converts a stored inline knowledge file into a data URL for backwards compatibility.
11745
+ */
11746
+ function inlineKnowledgeSourceToDataUrl(source) {
11747
+ const base64 = source.buffer.toString('base64');
11748
+ const encodedFilename = encodeURIComponent(source.filename);
11749
+ return `${DATA_URL_PREFIX}${source.mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
11750
+ }
11733
11751
  /**
11734
11752
  * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.
11735
11753
  *
11736
- * @private thing of inline knowledge
11754
+ * @private utility of inline knowledge processing
11737
11755
  */
11738
11756
  function parseDataUrlKnowledgeSource(source) {
11739
11757
  if (!isDataUrlKnowledgeSource(source)) {
@@ -11866,6 +11884,7 @@
11866
11884
  `);
11867
11885
  }
11868
11886
  applyToAgentModelRequirements(requirements, content) {
11887
+ var _a;
11869
11888
  const trimmedContent = content.trim();
11870
11889
  if (!trimmedContent) {
11871
11890
  return requirements;
@@ -11886,9 +11905,13 @@
11886
11905
  }
11887
11906
  else {
11888
11907
  const inlineSource = createInlineKnowledgeSourceFile(trimmedContent);
11908
+ const existingInlineSources = (((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.inlineKnowledgeSources) || []).slice();
11889
11909
  const updatedRequirements = {
11890
11910
  ...requirements,
11891
- knowledgeSources: [...(requirements.knowledgeSources || []), inlineSource.url],
11911
+ _metadata: {
11912
+ ...requirements._metadata,
11913
+ inlineKnowledgeSources: [...existingInlineSources, inlineSource],
11914
+ },
11892
11915
  };
11893
11916
  const knowledgeInfo = `Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`;
11894
11917
  return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
@@ -11970,6 +11993,237 @@
11970
11993
  * Note: [💞] Ignore a discrepancy between file name and entity name
11971
11994
  */
11972
11995
 
11996
+ /**
11997
+ * @@@
11998
+ *
11999
+ * @private utility for commitments
12000
+ */
12001
+ function formatOptionalInstructionBlock(label, content) {
12002
+ const trimmedContent = spaceTrim$1.spaceTrim(content);
12003
+ if (!trimmedContent) {
12004
+ return '';
12005
+ }
12006
+ return spaceTrim$1.spaceTrim((block) => `
12007
+ - ${label}:
12008
+ ${block(trimmedContent
12009
+ .split(/\r?\n/)
12010
+ .map((line) => `- ${line}`)
12011
+ .join('\n'))}
12012
+ `);
12013
+ }
12014
+
12015
+ /**
12016
+ * Prompt parameter key used to pass hidden runtime context to tool execution.
12017
+ *
12018
+ * @private internal runtime wiring for commitment tools
12019
+ */
12020
+ const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
12021
+ /**
12022
+ * Hidden argument key used to pass runtime context into individual tool calls.
12023
+ *
12024
+ * @private internal runtime wiring for commitment tools
12025
+ */
12026
+ const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
12027
+ /**
12028
+ * Parses unknown runtime context payload into a normalized object.
12029
+ *
12030
+ * @private internal runtime wiring for commitment tools
12031
+ */
12032
+ function parseToolRuntimeContext(rawValue) {
12033
+ if (!rawValue) {
12034
+ return null;
12035
+ }
12036
+ let parsed = rawValue;
12037
+ if (typeof rawValue === 'string') {
12038
+ try {
12039
+ parsed = JSON.parse(rawValue);
12040
+ }
12041
+ catch (_a) {
12042
+ return null;
12043
+ }
12044
+ }
12045
+ if (!parsed || typeof parsed !== 'object') {
12046
+ return null;
12047
+ }
12048
+ return parsed;
12049
+ }
12050
+ /**
12051
+ * Reads runtime context attached to tool call arguments.
12052
+ *
12053
+ * @private internal runtime wiring for commitment tools
12054
+ */
12055
+ function readToolRuntimeContextFromToolArgs(args) {
12056
+ return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
12057
+ }
12058
+ /**
12059
+ * Serializes runtime context for prompt parameters.
12060
+ *
12061
+ * @private internal runtime wiring for commitment tools
12062
+ */
12063
+ function serializeToolRuntimeContext(context) {
12064
+ return JSON.stringify(context);
12065
+ }
12066
+ /**
12067
+ * Note: [💞] Ignore a discrepancy between file name and entity name
12068
+ */
12069
+
12070
+ /**
12071
+ * Tool name used to retrieve persisted user memory.
12072
+ *
12073
+ * @private internal MEMORY commitment constant
12074
+ */
12075
+ const RETRIEVE_USER_MEMORY_TOOL_NAME = 'retrieve_user_memory';
12076
+ /**
12077
+ * Tool name used to store persisted user memory.
12078
+ *
12079
+ * @private internal MEMORY commitment constant
12080
+ */
12081
+ const STORE_USER_MEMORY_TOOL_NAME = 'store_user_memory';
12082
+ const UPDATE_USER_MEMORY_TOOL_NAME = 'update_user_memory';
12083
+ const DELETE_USER_MEMORY_TOOL_NAME = 'delete_user_memory';
12084
+ /**
12085
+ * Resolves runtime context from hidden tool arguments.
12086
+ *
12087
+ * @private utility of MEMORY commitment
12088
+ */
12089
+ function resolveMemoryRuntimeContext(args) {
12090
+ const runtimeContext = readToolRuntimeContextFromToolArgs(args);
12091
+ const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
12092
+ return {
12093
+ enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
12094
+ userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
12095
+ username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
12096
+ agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
12097
+ agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
12098
+ isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
12099
+ };
12100
+ }
12101
+ /**
12102
+ * Builds a disabled memory-tool response payload.
12103
+ *
12104
+ * @private utility of MEMORY commitment
12105
+ */
12106
+ function createDisabledMemoryResult(action, message) {
12107
+ if (action === 'retrieve') {
12108
+ return {
12109
+ action,
12110
+ status: 'disabled',
12111
+ memories: [],
12112
+ message,
12113
+ };
12114
+ }
12115
+ if (action === 'store') {
12116
+ return {
12117
+ action,
12118
+ status: 'disabled',
12119
+ message,
12120
+ };
12121
+ }
12122
+ if (action === 'update') {
12123
+ return {
12124
+ action,
12125
+ status: 'disabled',
12126
+ message,
12127
+ };
12128
+ }
12129
+ if (action === 'delete') {
12130
+ return {
12131
+ action,
12132
+ status: 'disabled',
12133
+ message,
12134
+ };
12135
+ }
12136
+ throw new Error(`Unsupported memory tool action: ${action}`);
12137
+ }
12138
+ /**
12139
+ * Gets the runtime adapter and returns a disabled result when unavailable.
12140
+ *
12141
+ * @private utility of MEMORY commitment
12142
+ */
12143
+ function getRuntimeAdapterOrDisabledResult(action, runtimeContext) {
12144
+ if (!runtimeContext.enabled || runtimeContext.isTeamConversation) {
12145
+ return {
12146
+ adapter: null,
12147
+ disabledResult: createDisabledMemoryResult(action, runtimeContext.isTeamConversation
12148
+ ? 'Memory is disabled for TEAM conversations.'
12149
+ : 'Memory is disabled for unauthenticated users.'),
12150
+ };
12151
+ }
12152
+ {
12153
+ return {
12154
+ adapter: null,
12155
+ disabledResult: createDisabledMemoryResult(action, 'Memory runtime is not available in this environment.'),
12156
+ };
12157
+ }
12158
+ }
12159
+ /**
12160
+ * Parses retrieve memory arguments.
12161
+ *
12162
+ * @private utility of MEMORY commitment
12163
+ */
12164
+ function parseRetrieveMemoryArgs(args) {
12165
+ const query = typeof args.query === 'string' ? args.query.trim() : undefined;
12166
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
12167
+ return {
12168
+ query: query && query.length > 0 ? query : undefined,
12169
+ limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
12170
+ };
12171
+ }
12172
+ /**
12173
+ * Parses store memory arguments.
12174
+ *
12175
+ * @private utility of MEMORY commitment
12176
+ */
12177
+ function parseStoreMemoryArgs(args) {
12178
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
12179
+ if (!content) {
12180
+ throw new Error('Memory content is required.');
12181
+ }
12182
+ return {
12183
+ content,
12184
+ isGlobal: args.isGlobal === true,
12185
+ };
12186
+ }
12187
+ /**
12188
+ * Parses a memory identifier argument shared across MEMORY tools.
12189
+ *
12190
+ * @private utility of MEMORY commitment
12191
+ */
12192
+ function parseMemoryIdArg(value) {
12193
+ const memoryId = typeof value === 'string' ? value.trim() : '';
12194
+ if (!memoryId) {
12195
+ throw new Error('Memory id is required.');
12196
+ }
12197
+ return memoryId;
12198
+ }
12199
+ /**
12200
+ * Parses update memory arguments.
12201
+ *
12202
+ * @private utility of MEMORY commitment
12203
+ */
12204
+ function parseUpdateMemoryArgs(args) {
12205
+ const memoryId = parseMemoryIdArg(args.memoryId);
12206
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
12207
+ if (!content) {
12208
+ throw new Error('Memory content is required.');
12209
+ }
12210
+ const isGlobal = typeof args.isGlobal === 'boolean' ? args.isGlobal : undefined;
12211
+ return {
12212
+ memoryId,
12213
+ content,
12214
+ isGlobal,
12215
+ };
12216
+ }
12217
+ /**
12218
+ * Parses delete memory arguments.
12219
+ *
12220
+ * @private utility of MEMORY commitment
12221
+ */
12222
+ function parseDeleteMemoryArgs(args) {
12223
+ return {
12224
+ memoryId: parseMemoryIdArg(args.memoryId),
12225
+ };
12226
+ }
11973
12227
  /**
11974
12228
  * MEMORY commitment definition
11975
12229
  *
@@ -11991,6 +12245,9 @@
11991
12245
  constructor(type = 'MEMORY') {
11992
12246
  super(type);
11993
12247
  }
12248
+ get requiresContent() {
12249
+ return false;
12250
+ }
11994
12251
  /**
11995
12252
  * Short one-line description of MEMORY.
11996
12253
  */
@@ -12010,21 +12267,14 @@
12010
12267
  return spaceTrim$1.spaceTrim(`
12011
12268
  # ${this.type}
12012
12269
 
12013
- 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.
12270
+ Enables persistent user memory for the current agent. The memory is stored by the runtime and can be retrieved in future conversations.
12014
12271
 
12015
12272
  ## Key aspects
12016
12273
 
12017
- - Both terms work identically and can be used interchangeably.
12018
- - Focuses on user-specific information and interaction history.
12019
- - Helps personalize responses based on past interactions.
12020
- - Maintains continuity across conversations.
12021
-
12022
- ## Differences from KNOWLEDGE
12023
-
12024
- - \`KNOWLEDGE\` is for domain expertise and factual information
12025
- - \`MEMORY\` is for user-specific context and preferences
12026
- - \`MEMORY\` creates more personalized interactions
12027
- - \`MEMORY\` often includes temporal or preference-based information
12274
+ - Both \`MEMORY\` and \`MEMORIES\` work identically.
12275
+ - Stores user-specific details through runtime tools.
12276
+ - Retrieves relevant memories for personalized responses.
12277
+ - Supports optional extra instructions in the commitment content.
12028
12278
 
12029
12279
  ## Examples
12030
12280
 
@@ -12032,10 +12282,7 @@
12032
12282
  Personal Assistant
12033
12283
 
12034
12284
  PERSONA You are a personal productivity assistant
12035
- MEMORY User is a software developer working in JavaScript/React
12036
- MEMORY User prefers morning work sessions and afternoon meetings
12037
- MEMORY Previously helped with project planning for mobile apps
12038
- MEMORY User timezone: UTC-8 (Pacific Time)
12285
+ MEMORY Remember user projects and long-term preferences.
12039
12286
  GOAL Help optimize daily productivity and workflow
12040
12287
  \`\`\`
12041
12288
 
@@ -12043,10 +12290,7 @@
12043
12290
  Learning Companion
12044
12291
 
12045
12292
  PERSONA You are an educational companion for programming students
12046
- MEMORY Student is learning Python as their first programming language
12047
- MEMORY Previous topics covered: variables, loops, functions
12048
- MEMORY Student learns best with practical examples and exercises
12049
- MEMORY Last session: working on list comprehensions
12293
+ MEMORY Remember only the student's learning progress and preferred study style.
12050
12294
  GOAL Provide progressive learning experiences tailored to student's pace
12051
12295
  \`\`\`
12052
12296
 
@@ -12054,23 +12298,245 @@
12054
12298
  Customer Support Agent
12055
12299
 
12056
12300
  PERSONA You are a customer support representative
12057
- MEMORY Customer has premium subscription since 2023
12058
- MEMORY Previous issue: billing question resolved last month
12059
- MEMORY Customer prefers email communication over phone calls
12060
- MEMORY Account shows frequent use of advanced features
12301
+ MEMORY Remember only important support history and communication preferences.
12061
12302
  GOAL Provide personalized support based on customer history
12062
12303
  \`\`\`
12063
12304
  `);
12064
12305
  }
12065
12306
  applyToAgentModelRequirements(requirements, content) {
12066
- const trimmedContent = content.trim();
12067
- if (!trimmedContent) {
12068
- return requirements;
12307
+ const extraInstructions = formatOptionalInstructionBlock('Memory instructions', content);
12308
+ const existingTools = requirements.tools || [];
12309
+ const tools = [...existingTools];
12310
+ if (!tools.some((tool) => tool.name === RETRIEVE_USER_MEMORY_TOOL_NAME)) {
12311
+ tools.push({
12312
+ name: RETRIEVE_USER_MEMORY_TOOL_NAME,
12313
+ description: spaceTrim$1.spaceTrim(`
12314
+ Retrieve previously stored user memories relevant to the current conversation.
12315
+ Use this before responding when user context can improve the answer.
12316
+ `),
12317
+ parameters: {
12318
+ type: 'object',
12319
+ properties: {
12320
+ query: {
12321
+ type: 'string',
12322
+ description: 'Optional query used to filter relevant memories.',
12323
+ },
12324
+ limit: {
12325
+ type: 'integer',
12326
+ description: 'Optional maximum number of memories to return (default 5, max 20).',
12327
+ },
12328
+ },
12329
+ },
12330
+ });
12331
+ }
12332
+ if (!tools.some((tool) => tool.name === STORE_USER_MEMORY_TOOL_NAME)) {
12333
+ tools.push({
12334
+ name: STORE_USER_MEMORY_TOOL_NAME,
12335
+ description: spaceTrim$1.spaceTrim(`
12336
+ Store a durable user memory that should be remembered in future conversations.
12337
+ Store only stable and useful user-specific facts or preferences.
12338
+ `),
12339
+ parameters: {
12340
+ type: 'object',
12341
+ properties: {
12342
+ content: {
12343
+ type: 'string',
12344
+ description: 'Memory text to store.',
12345
+ },
12346
+ isGlobal: {
12347
+ type: 'boolean',
12348
+ description: 'Set true to make this memory global across all user agents.',
12349
+ },
12350
+ },
12351
+ required: ['content'],
12352
+ },
12353
+ });
12354
+ }
12355
+ if (!tools.some((tool) => tool.name === UPDATE_USER_MEMORY_TOOL_NAME)) {
12356
+ tools.push({
12357
+ name: UPDATE_USER_MEMORY_TOOL_NAME,
12358
+ description: spaceTrim$1.spaceTrim(`
12359
+ Update an existing user memory after retrieving it, so the stored fact stays accurate.
12360
+ Always pass the memory id you retrieved along with the new content.
12361
+ `),
12362
+ parameters: {
12363
+ type: 'object',
12364
+ properties: {
12365
+ memoryId: {
12366
+ type: 'string',
12367
+ description: 'Unique identifier of the memory entry to update.',
12368
+ },
12369
+ content: {
12370
+ type: 'string',
12371
+ description: 'Updated memory text.',
12372
+ },
12373
+ isGlobal: {
12374
+ type: 'boolean',
12375
+ description: 'Set true to keep the fact global; omit or false to keep it agent-scoped.',
12376
+ },
12377
+ },
12378
+ required: ['memoryId', 'content'],
12379
+ },
12380
+ });
12069
12381
  }
12070
- // Create memory section for system message
12071
- const memorySection = `Memory: ${trimmedContent}`;
12072
- // Memory information is contextual and should be included in the system message
12073
- return this.appendToSystemMessage(requirements, memorySection, '\n\n');
12382
+ if (!tools.some((tool) => tool.name === DELETE_USER_MEMORY_TOOL_NAME)) {
12383
+ tools.push({
12384
+ name: DELETE_USER_MEMORY_TOOL_NAME,
12385
+ description: spaceTrim$1.spaceTrim(`
12386
+ Delete a user memory that is no longer relevant. Deletions are soft so the record is hidden from future queries.
12387
+ `),
12388
+ parameters: {
12389
+ type: 'object',
12390
+ properties: {
12391
+ memoryId: {
12392
+ type: 'string',
12393
+ description: 'Unique identifier of the memory entry to delete.',
12394
+ },
12395
+ },
12396
+ required: ['memoryId'],
12397
+ },
12398
+ });
12399
+ }
12400
+ return this.appendToSystemMessage({
12401
+ ...requirements,
12402
+ tools,
12403
+ _metadata: {
12404
+ ...requirements._metadata,
12405
+ useMemory: content || true,
12406
+ },
12407
+ }, spaceTrim$1.spaceTrim((block) => `
12408
+ Memory:
12409
+ - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
12410
+ - You can use persistent user memory tools.
12411
+ - Use "${RETRIEVE_USER_MEMORY_TOOL_NAME}" to load relevant memory before answering.
12412
+ - Use "${STORE_USER_MEMORY_TOOL_NAME}" to save stable user-specific facts that improve future help.
12413
+ - Use "${UPDATE_USER_MEMORY_TOOL_NAME}" to refresh an existing memory when the content changes.
12414
+ - Use "${DELETE_USER_MEMORY_TOOL_NAME}" to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
12415
+ - Store concise memory items and avoid duplicates.
12416
+ - Never claim memory was saved or loaded unless the tool confirms it.
12417
+ ${block(extraInstructions)}
12418
+ `));
12419
+ }
12420
+ /**
12421
+ * Gets human-readable titles for MEMORY tool functions.
12422
+ */
12423
+ getToolTitles() {
12424
+ return {
12425
+ [RETRIEVE_USER_MEMORY_TOOL_NAME]: 'User memory',
12426
+ [STORE_USER_MEMORY_TOOL_NAME]: 'Store user memory',
12427
+ [UPDATE_USER_MEMORY_TOOL_NAME]: 'Update user memory',
12428
+ [DELETE_USER_MEMORY_TOOL_NAME]: 'Delete user memory',
12429
+ };
12430
+ }
12431
+ /**
12432
+ * Gets MEMORY tool function implementations.
12433
+ */
12434
+ getToolFunctions() {
12435
+ return {
12436
+ async [RETRIEVE_USER_MEMORY_TOOL_NAME](args) {
12437
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12438
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
12439
+ if (!adapter || disabledResult) {
12440
+ return JSON.stringify(disabledResult);
12441
+ }
12442
+ const parsedArgs = parseRetrieveMemoryArgs(args);
12443
+ try {
12444
+ const memories = await adapter.retrieveMemories(parsedArgs, runtimeContext);
12445
+ const result = {
12446
+ action: 'retrieve',
12447
+ status: 'ok',
12448
+ query: parsedArgs.query,
12449
+ memories,
12450
+ };
12451
+ return JSON.stringify(result);
12452
+ }
12453
+ catch (error) {
12454
+ const result = {
12455
+ action: 'retrieve',
12456
+ status: 'error',
12457
+ query: parsedArgs.query,
12458
+ memories: [],
12459
+ message: error instanceof Error ? error.message : String(error),
12460
+ };
12461
+ return JSON.stringify(result);
12462
+ }
12463
+ },
12464
+ async [STORE_USER_MEMORY_TOOL_NAME](args) {
12465
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12466
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('store', runtimeContext);
12467
+ if (!adapter || disabledResult) {
12468
+ return JSON.stringify(disabledResult);
12469
+ }
12470
+ try {
12471
+ const parsedArgs = parseStoreMemoryArgs(args);
12472
+ const memory = await adapter.storeMemory(parsedArgs, runtimeContext);
12473
+ const result = {
12474
+ action: 'store',
12475
+ status: 'stored',
12476
+ memory,
12477
+ };
12478
+ return JSON.stringify(result);
12479
+ }
12480
+ catch (error) {
12481
+ const result = {
12482
+ action: 'store',
12483
+ status: 'error',
12484
+ message: error instanceof Error ? error.message : String(error),
12485
+ };
12486
+ return JSON.stringify(result);
12487
+ }
12488
+ },
12489
+ async [UPDATE_USER_MEMORY_TOOL_NAME](args) {
12490
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12491
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('update', runtimeContext);
12492
+ if (!adapter || disabledResult) {
12493
+ return JSON.stringify(disabledResult);
12494
+ }
12495
+ try {
12496
+ const parsedArgs = parseUpdateMemoryArgs(args);
12497
+ const memory = await adapter.updateMemory(parsedArgs, runtimeContext);
12498
+ const result = {
12499
+ action: 'update',
12500
+ status: 'updated',
12501
+ memory,
12502
+ };
12503
+ return JSON.stringify(result);
12504
+ }
12505
+ catch (error) {
12506
+ const result = {
12507
+ action: 'update',
12508
+ status: 'error',
12509
+ message: error instanceof Error ? error.message : String(error),
12510
+ };
12511
+ return JSON.stringify(result);
12512
+ }
12513
+ },
12514
+ async [DELETE_USER_MEMORY_TOOL_NAME](args) {
12515
+ const runtimeContext = resolveMemoryRuntimeContext(args);
12516
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('delete', runtimeContext);
12517
+ if (!adapter || disabledResult) {
12518
+ return JSON.stringify(disabledResult);
12519
+ }
12520
+ try {
12521
+ const parsedArgs = parseDeleteMemoryArgs(args);
12522
+ const deleted = await adapter.deleteMemory(parsedArgs, runtimeContext);
12523
+ const result = {
12524
+ action: 'delete',
12525
+ status: 'deleted',
12526
+ memoryId: deleted.id,
12527
+ };
12528
+ return JSON.stringify(result);
12529
+ }
12530
+ catch (error) {
12531
+ const result = {
12532
+ action: 'delete',
12533
+ status: 'error',
12534
+ message: error instanceof Error ? error.message : String(error),
12535
+ };
12536
+ return JSON.stringify(result);
12537
+ }
12538
+ },
12539
+ };
12074
12540
  }
12075
12541
  }
12076
12542
  /**
@@ -14183,14 +14649,30 @@
14183
14649
  /**
14184
14650
  * Builds a minimal chat prompt for teammate calls.
14185
14651
  */
14186
- function buildTeammatePrompt(request) {
14652
+ function buildTeammatePrompt(request, runtimeContext) {
14187
14653
  return {
14188
14654
  title: 'Teammate consultation',
14189
14655
  modelRequirements: {
14190
14656
  modelVariant: 'CHAT',
14191
14657
  },
14192
14658
  content: request,
14193
- parameters: {},
14659
+ parameters: {
14660
+ [TOOL_RUNTIME_CONTEXT_PARAMETER]: serializeToolRuntimeContext(runtimeContext),
14661
+ },
14662
+ };
14663
+ }
14664
+ /**
14665
+ * Creates teammate runtime context and marks conversation as team-only memory-disabled.
14666
+ */
14667
+ function createTeamConversationRuntimeContext(value) {
14668
+ const runtimeContext = parseToolRuntimeContext(value) || {};
14669
+ return {
14670
+ ...runtimeContext,
14671
+ memory: {
14672
+ ...(runtimeContext.memory || {}),
14673
+ enabled: false,
14674
+ isTeamConversation: true,
14675
+ },
14194
14676
  };
14195
14677
  }
14196
14678
  /**
@@ -14234,7 +14716,7 @@
14234
14716
  let toolCalls;
14235
14717
  try {
14236
14718
  const remoteAgent = await getRemoteTeammateAgent(entry.teammate.url);
14237
- const prompt = buildTeammatePrompt(request);
14719
+ const prompt = buildTeammatePrompt(request, createTeamConversationRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]));
14238
14720
  const teammateResult = await remoteAgent.callChatModel(prompt);
14239
14721
  response = teammateResult.content || '';
14240
14722
  toolCalls =
@@ -14784,25 +15266,6 @@
14784
15266
  * Note: [💞] Ignore a discrepancy between file name and entity name
14785
15267
  */
14786
15268
 
14787
- /**
14788
- * @@@
14789
- *
14790
- * @private utility for commitments
14791
- */
14792
- function formatOptionalInstructionBlock(label, content) {
14793
- const trimmedContent = spaceTrim$1.spaceTrim(content);
14794
- if (!trimmedContent) {
14795
- return '';
14796
- }
14797
- return spaceTrim$1.spaceTrim((block) => `
14798
- - ${label}:
14799
- ${block(trimmedContent
14800
- .split(/\r?\n/)
14801
- .map((line) => `- ${line}`)
14802
- .join('\n'))}
14803
- `);
14804
- }
14805
-
14806
15269
  /**
14807
15270
  * Client-side safe wrapper for sending emails.
14808
15271
  *
@@ -14996,8 +15459,8 @@
14996
15459
  /**
14997
15460
  * USE IMAGE GENERATOR commitment definition
14998
15461
  *
14999
- * The `USE IMAGE GENERATOR` commitment indicates that the agent should utilize an image generation tool
15000
- * to create images based on text prompts.
15462
+ * The `USE IMAGE GENERATOR` commitment indicates that the agent can output
15463
+ * markdown placeholders for UI-driven image generation.
15001
15464
  *
15002
15465
  * Example usage in agent source:
15003
15466
  *
@@ -15012,11 +15475,14 @@
15012
15475
  constructor(type = 'USE IMAGE GENERATOR') {
15013
15476
  super(type, ['USE IMAGE GENERATION', 'IMAGE GENERATOR', 'IMAGE GENERATION', 'USE IMAGE']);
15014
15477
  }
15478
+ get requiresContent() {
15479
+ return false;
15480
+ }
15015
15481
  /**
15016
15482
  * Short one-line description of USE IMAGE GENERATOR.
15017
15483
  */
15018
15484
  get description() {
15019
- return 'Enable the agent to use an image generation tool for creating images from text prompts.';
15485
+ return 'Enable the agent to output markdown image placeholders that the UI turns into generated images.';
15020
15486
  }
15021
15487
  /**
15022
15488
  * Icon for this commitment.
@@ -15031,21 +15497,21 @@
15031
15497
  return spaceTrim$1.spaceTrim(`
15032
15498
  # USE IMAGE GENERATOR
15033
15499
 
15034
- Enables the agent to use an image generation tool to create images based on text prompts.
15500
+ Enables the agent to output markdown image placeholders that trigger image generation in the user interface.
15035
15501
 
15036
15502
  ## Key aspects
15037
15503
 
15038
15504
  - The content following \`USE IMAGE GENERATOR\` is an arbitrary text that the agent should know (e.g. style instructions or safety guidelines).
15039
- - The actual image generation is handled by the agent runtime using LLM execution tools.
15040
- - Allows the agent to generate visual content based on user requests.
15041
- - Returns the URL of the generated image.
15505
+ - The agent does **not** call an image-generation tool directly.
15506
+ - The agent inserts markdown notation: \`![alt](?image-prompt=...)\`.
15507
+ - The user interface detects the notation and generates the image asynchronously.
15042
15508
 
15043
15509
  ## Examples
15044
15510
 
15045
15511
  \`\`\`book
15046
15512
  Visual Artist
15047
15513
 
15048
- PERSONA You are a creative visual artist who can generate images.
15514
+ PERSONA You are a creative visual artist.
15049
15515
  USE IMAGE GENERATOR
15050
15516
  RULE Always describe the generated image to the user.
15051
15517
  \`\`\`
@@ -15055,80 +15521,28 @@
15055
15521
 
15056
15522
  PERSONA You are an interior designer who helps users visualize their space.
15057
15523
  USE IMAGE GENERATOR Professional interior design renders.
15058
- ACTION Generate a preview of the designed room.
15524
+ ACTION Add one generated image placeholder whenever a user asks for a visual.
15059
15525
  \`\`\`
15060
15526
  `);
15061
15527
  }
15062
15528
  applyToAgentModelRequirements(requirements, content) {
15063
- // Get existing tools array or create new one
15064
- const existingTools = requirements.tools || [];
15065
- // Add 'generate_image' to tools if not already present
15066
- const updatedTools = existingTools.some((tool) => tool.name === 'generate_image')
15067
- ? existingTools
15068
- : [
15069
- ...existingTools,
15070
- {
15071
- name: 'generate_image',
15072
- description: spaceTrim$1.spaceTrim(`
15073
- Generate an image from a text prompt.
15074
- Use this tool when the user asks to create, draw, or generate an image.
15075
- ${!content ? '' : `Style instructions / guidelines: ${content}`}
15076
- `),
15077
- parameters: {
15078
- type: 'object',
15079
- properties: {
15080
- prompt: {
15081
- type: 'string',
15082
- description: 'The detailed description of the image to generate',
15083
- },
15084
- },
15085
- required: ['prompt'],
15086
- },
15087
- },
15088
- ];
15089
- // Return requirements with updated tools and metadata
15529
+ const extraInstructions = formatOptionalInstructionBlock('Image instructions', content);
15090
15530
  return this.appendToSystemMessage({
15091
15531
  ...requirements,
15092
- tools: updatedTools,
15093
15532
  _metadata: {
15094
15533
  ...requirements._metadata,
15095
15534
  useImageGenerator: content || true,
15096
15535
  },
15097
- }, spaceTrim$1.spaceTrim(`
15098
- You have access to an image generator. Use it to create images based on user requests.
15099
- When you generate an image, you will receive a URL of the generated image.
15100
- `));
15101
- }
15102
- /**
15103
- * Gets human-readable titles for tool functions provided by this commitment.
15104
- */
15105
- getToolTitles() {
15106
- return {
15107
- generate_image: 'Generate image',
15108
- };
15109
- }
15110
- /**
15111
- * Gets the `generate_image` tool function implementation.
15112
- */
15113
- getToolFunctions() {
15114
- return {
15115
- async generate_image(args, ...extra) {
15116
- console.log('!!!! [Tool] generate_image called', { args });
15117
- const { prompt } = args;
15118
- if (!prompt) {
15119
- throw new Error('Image prompt is required');
15120
- }
15121
- const { llmTools } = extra[0] || {};
15122
- if (!llmTools || !llmTools.callImageGenerationModel) {
15123
- throw new Error('Image generation is not supported by the current model provider');
15124
- }
15125
- const result = await llmTools.callImageGenerationModel({
15126
- content: prompt,
15127
- modelName: 'dall-e-3', // Defaulting to dall-e-3, but this could be configurable
15128
- });
15129
- return result.content;
15130
- },
15131
- };
15536
+ }, spaceTrim$1.spaceTrim((block) => `
15537
+ Image generation:
15538
+ - You do not generate images directly and you do not call any image tool.
15539
+ - When the user asks for an image, include markdown notation in your message:
15540
+ \`![<alt text>](?image-prompt=<prompt>)\`
15541
+ - Keep \`<alt text>\` short and descriptive.
15542
+ - Keep \`<prompt>\` detailed so the generated image matches the request.
15543
+ - You can include normal explanatory text before and after the notation.
15544
+ ${block(extraInstructions)}
15545
+ `));
15132
15546
  }
15133
15547
  }
15134
15548
  /**
@@ -18617,6 +19031,7 @@
18617
19031
  systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
18618
19032
  };
18619
19033
  }
19034
+ requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
18620
19035
  // Remove comment lines (lines starting with #) from the final system message
18621
19036
  // while preserving the original content with comments in metadata
18622
19037
  const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
@@ -18625,6 +19040,54 @@
18625
19040
  systemMessage: cleanedSystemMessage,
18626
19041
  };
18627
19042
  }
19043
+ /**
19044
+ * @private Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
19045
+ */
19046
+ async function applyPendingInlineKnowledgeSources(requirements, uploader) {
19047
+ var _a;
19048
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
19049
+ if (inlineSources.length === 0) {
19050
+ return requirements;
19051
+ }
19052
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
19053
+ for (const inlineSource of inlineSources) {
19054
+ const url = uploader
19055
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
19056
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
19057
+ knowledgeSources.push(url);
19058
+ }
19059
+ return {
19060
+ ...requirements,
19061
+ knowledgeSources,
19062
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
19063
+ };
19064
+ }
19065
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
19066
+ try {
19067
+ return await uploader(inlineSource);
19068
+ }
19069
+ catch (error) {
19070
+ console.error('[inline-knowledge] Failed to upload inline source', {
19071
+ filename: inlineSource.filename,
19072
+ error,
19073
+ });
19074
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
19075
+ }
19076
+ }
19077
+ function extractInlineKnowledgeSources(metadata) {
19078
+ if (!metadata) {
19079
+ return [];
19080
+ }
19081
+ const value = metadata.inlineKnowledgeSources;
19082
+ return Array.isArray(value) ? value : [];
19083
+ }
19084
+ function stripInlineKnowledgeMetadata(metadata) {
19085
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
19086
+ return metadata;
19087
+ }
19088
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
19089
+ return Object.keys(rest).length > 0 ? rest : undefined;
19090
+ }
18628
19091
  /**
18629
19092
  * Mocked security check for imported files
18630
19093
  *
@@ -19684,6 +20147,28 @@
19684
20147
  }));
19685
20148
  }
19686
20149
 
20150
+ /**
20151
+ * Builds a tool invocation script that injects hidden runtime context into tool args.
20152
+ *
20153
+ * @private utility of OpenAI tool execution wrappers
20154
+ */
20155
+ function buildToolInvocationScript(options) {
20156
+ const { functionName, functionArgsExpression } = options;
20157
+ return `
20158
+ const args = ${functionArgsExpression};
20159
+ const runtimeContextRaw =
20160
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
20161
+ ? undefined
20162
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
20163
+
20164
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
20165
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
20166
+ }
20167
+
20168
+ return await ${functionName}(args);
20169
+ `;
20170
+ }
20171
+
19687
20172
  /**
19688
20173
  * Parses an OpenAI error message to identify which parameter is unsupported
19689
20174
  *
@@ -20037,10 +20522,10 @@
20037
20522
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
20038
20523
  functionResponse = await scriptTool.execute({
20039
20524
  scriptLanguage: 'javascript',
20040
- script: `
20041
- const args = ${functionArgs};
20042
- return await ${functionName}(args);
20043
- `,
20525
+ script: buildToolInvocationScript({
20526
+ functionName,
20527
+ functionArgsExpression: functionArgs,
20528
+ }),
20044
20529
  parameters: prompt.parameters,
20045
20530
  });
20046
20531
  }
@@ -21742,10 +22227,10 @@
21742
22227
  try {
21743
22228
  return await scriptTool.execute({
21744
22229
  scriptLanguage: 'javascript',
21745
- script: `
21746
- const args = ${JSON.stringify(functionArgs)};
21747
- return await ${functionName}(args);
21748
- `,
22230
+ script: buildToolInvocationScript({
22231
+ functionName,
22232
+ functionArgsExpression: JSON.stringify(functionArgs),
22233
+ }),
21749
22234
  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 : {},
21750
22235
  });
21751
22236
  }
@@ -22198,10 +22683,10 @@
22198
22683
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
22199
22684
  functionResponse = await scriptTool.execute({
22200
22685
  scriptLanguage: 'javascript',
22201
- script: `
22202
- const args = ${JSON.stringify(functionArgs)};
22203
- return await ${functionName}(args);
22204
- `,
22686
+ script: buildToolInvocationScript({
22687
+ functionName,
22688
+ functionArgsExpression: JSON.stringify(functionArgs),
22689
+ }),
22205
22690
  parameters: prompt.parameters,
22206
22691
  });
22207
22692
  if (this.options.isVerbose) {
@@ -23417,6 +23902,20 @@
23417
23902
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
23418
23903
  */
23419
23904
 
23905
+ /**
23906
+ * Keep-alive helpers used for streaming chat responses.
23907
+ *
23908
+ * These constants coordinate the signal sent by the Agents Server streaming
23909
+ * endpoint and the parser in the SDK so we can distinguish between
23910
+ * real content and occasional pings.
23911
+ *
23912
+ * @private internal streaming helper for Promptbook chat connections
23913
+ */
23914
+ const CHAT_STREAM_KEEP_ALIVE_TOKEN = 'STREAM_KEEP_ALIVE';
23915
+ /**
23916
+ * Note: [💞] Ignore a discrepancy between file name and entity name
23917
+ */
23918
+
23420
23919
  /**
23421
23920
  * Resolve a remote META IMAGE value into an absolute URL when possible.
23422
23921
  */
@@ -23491,7 +23990,9 @@
23491
23990
  static async connect(options) {
23492
23991
  var _a, _b, _c;
23493
23992
  const agentProfileUrl = `${options.agentUrl}/api/profile`;
23494
- const profileResponse = await fetch(agentProfileUrl);
23993
+ const profileResponse = await fetch(agentProfileUrl, {
23994
+ headers: attachClientVersionHeader(),
23995
+ });
23495
23996
  // <- TODO: [🐱‍🚀] What about closed-source agents?
23496
23997
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
23497
23998
  if (!profileResponse.ok) {
@@ -23592,6 +24093,7 @@
23592
24093
  }
23593
24094
  const response = await fetch(`${this.agentUrl}/api/voice`, {
23594
24095
  method: 'POST',
24096
+ headers: attachClientVersionHeader(),
23595
24097
  body: formData,
23596
24098
  });
23597
24099
  if (!response.ok) {
@@ -23621,13 +24123,14 @@
23621
24123
  const chatPrompt = prompt;
23622
24124
  const bookResponse = await fetch(`${this.agentUrl}/api/chat`, {
23623
24125
  method: 'POST',
23624
- headers: {
24126
+ headers: attachClientVersionHeader({
23625
24127
  'Content-Type': 'application/json',
23626
- },
24128
+ }),
23627
24129
  body: JSON.stringify({
23628
24130
  message: prompt.content,
23629
24131
  thread: chatPrompt.thread,
23630
24132
  attachments: chatPrompt.attachments,
24133
+ parameters: chatPrompt.parameters,
23631
24134
  }),
23632
24135
  });
23633
24136
  // <- TODO: [🐱‍🚀] What about closed-source agents?
@@ -23709,6 +24212,9 @@
23709
24212
  const lines = textChunk.split(/\r?\n/);
23710
24213
  for (const line of lines) {
23711
24214
  const trimmedLine = line.trim();
24215
+ if (trimmedLine === CHAT_STREAM_KEEP_ALIVE_TOKEN) {
24216
+ continue;
24217
+ }
23712
24218
  let isToolCallLine = false;
23713
24219
  if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
23714
24220
  try {