@promptbook/remote-server 0.110.0 → 0.111.0-0

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 (29) hide show
  1. package/README.md +4 -0
  2. package/esm/index.es.js +654 -99
  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/save/_common/ChatSaveFormatDefinition.d.ts +7 -1
  11. package/esm/typings/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +6 -5
  12. package/esm/typings/src/book-components/Chat/save/index.d.ts +3 -3
  13. package/esm/typings/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +11 -0
  14. package/esm/typings/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +2 -2
  15. package/esm/typings/src/book-components/Chat/utils/parseImagePrompts.d.ts +42 -0
  16. package/esm/typings/src/book-components/Chat/utils/parseImagePrompts.test.d.ts +1 -0
  17. package/esm/typings/src/commitments/MEMORY/MEMORY.d.ts +67 -0
  18. package/esm/typings/src/commitments/MEMORY/MEMORY.test.d.ts +1 -0
  19. package/esm/typings/src/commitments/_common/toolRuntimeContext.d.ts +49 -0
  20. package/esm/typings/src/constants/streaming.d.ts +20 -0
  21. package/esm/typings/src/llm-providers/openai/utils/buildToolInvocationScript.d.ts +9 -0
  22. package/esm/typings/src/utils/clientVersion.d.ts +51 -0
  23. package/esm/typings/src/utils/knowledge/inlineKnowledgeSource.d.ts +13 -9
  24. package/esm/typings/src/utils/normalization/constructImageFilename.d.ts +18 -0
  25. package/esm/typings/src/utils/normalization/constructImageFilename.test.d.ts +1 -0
  26. package/esm/typings/src/version.d.ts +1 -1
  27. package/package.json +2 -2
  28. package/umd/index.umd.js +654 -99
  29. 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-0';
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
+ });
12381
+ }
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
+ });
12069
12399
  }
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');
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
  *
@@ -18617,6 +19080,7 @@
18617
19080
  systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
18618
19081
  };
18619
19082
  }
19083
+ requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
18620
19084
  // Remove comment lines (lines starting with #) from the final system message
18621
19085
  // while preserving the original content with comments in metadata
18622
19086
  const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
@@ -18625,6 +19089,54 @@
18625
19089
  systemMessage: cleanedSystemMessage,
18626
19090
  };
18627
19091
  }
19092
+ /**
19093
+ * @private Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
19094
+ */
19095
+ async function applyPendingInlineKnowledgeSources(requirements, uploader) {
19096
+ var _a;
19097
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
19098
+ if (inlineSources.length === 0) {
19099
+ return requirements;
19100
+ }
19101
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
19102
+ for (const inlineSource of inlineSources) {
19103
+ const url = uploader
19104
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
19105
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
19106
+ knowledgeSources.push(url);
19107
+ }
19108
+ return {
19109
+ ...requirements,
19110
+ knowledgeSources,
19111
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
19112
+ };
19113
+ }
19114
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
19115
+ try {
19116
+ return await uploader(inlineSource);
19117
+ }
19118
+ catch (error) {
19119
+ console.error('[inline-knowledge] Failed to upload inline source', {
19120
+ filename: inlineSource.filename,
19121
+ error,
19122
+ });
19123
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
19124
+ }
19125
+ }
19126
+ function extractInlineKnowledgeSources(metadata) {
19127
+ if (!metadata) {
19128
+ return [];
19129
+ }
19130
+ const value = metadata.inlineKnowledgeSources;
19131
+ return Array.isArray(value) ? value : [];
19132
+ }
19133
+ function stripInlineKnowledgeMetadata(metadata) {
19134
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
19135
+ return metadata;
19136
+ }
19137
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
19138
+ return Object.keys(rest).length > 0 ? rest : undefined;
19139
+ }
18628
19140
  /**
18629
19141
  * Mocked security check for imported files
18630
19142
  *
@@ -19684,6 +20196,28 @@
19684
20196
  }));
19685
20197
  }
19686
20198
 
20199
+ /**
20200
+ * Builds a tool invocation script that injects hidden runtime context into tool args.
20201
+ *
20202
+ * @private utility of OpenAI tool execution wrappers
20203
+ */
20204
+ function buildToolInvocationScript(options) {
20205
+ const { functionName, functionArgsExpression } = options;
20206
+ return `
20207
+ const args = ${functionArgsExpression};
20208
+ const runtimeContextRaw =
20209
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
20210
+ ? undefined
20211
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
20212
+
20213
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
20214
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
20215
+ }
20216
+
20217
+ return await ${functionName}(args);
20218
+ `;
20219
+ }
20220
+
19687
20221
  /**
19688
20222
  * Parses an OpenAI error message to identify which parameter is unsupported
19689
20223
  *
@@ -20037,10 +20571,10 @@
20037
20571
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
20038
20572
  functionResponse = await scriptTool.execute({
20039
20573
  scriptLanguage: 'javascript',
20040
- script: `
20041
- const args = ${functionArgs};
20042
- return await ${functionName}(args);
20043
- `,
20574
+ script: buildToolInvocationScript({
20575
+ functionName,
20576
+ functionArgsExpression: functionArgs,
20577
+ }),
20044
20578
  parameters: prompt.parameters,
20045
20579
  });
20046
20580
  }
@@ -21742,10 +22276,10 @@
21742
22276
  try {
21743
22277
  return await scriptTool.execute({
21744
22278
  scriptLanguage: 'javascript',
21745
- script: `
21746
- const args = ${JSON.stringify(functionArgs)};
21747
- return await ${functionName}(args);
21748
- `,
22279
+ script: buildToolInvocationScript({
22280
+ functionName,
22281
+ functionArgsExpression: JSON.stringify(functionArgs),
22282
+ }),
21749
22283
  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
22284
  });
21751
22285
  }
@@ -22198,10 +22732,10 @@
22198
22732
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
22199
22733
  functionResponse = await scriptTool.execute({
22200
22734
  scriptLanguage: 'javascript',
22201
- script: `
22202
- const args = ${JSON.stringify(functionArgs)};
22203
- return await ${functionName}(args);
22204
- `,
22735
+ script: buildToolInvocationScript({
22736
+ functionName,
22737
+ functionArgsExpression: JSON.stringify(functionArgs),
22738
+ }),
22205
22739
  parameters: prompt.parameters,
22206
22740
  });
22207
22741
  if (this.options.isVerbose) {
@@ -23417,6 +23951,20 @@
23417
23951
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?
23418
23952
  */
23419
23953
 
23954
+ /**
23955
+ * Keep-alive helpers used for streaming chat responses.
23956
+ *
23957
+ * These constants coordinate the signal sent by the Agents Server streaming
23958
+ * endpoint and the parser in the SDK so we can distinguish between
23959
+ * real content and occasional pings.
23960
+ *
23961
+ * @private internal streaming helper for Promptbook chat connections
23962
+ */
23963
+ const CHAT_STREAM_KEEP_ALIVE_TOKEN = 'STREAM_KEEP_ALIVE';
23964
+ /**
23965
+ * Note: [💞] Ignore a discrepancy between file name and entity name
23966
+ */
23967
+
23420
23968
  /**
23421
23969
  * Resolve a remote META IMAGE value into an absolute URL when possible.
23422
23970
  */
@@ -23491,7 +24039,9 @@
23491
24039
  static async connect(options) {
23492
24040
  var _a, _b, _c;
23493
24041
  const agentProfileUrl = `${options.agentUrl}/api/profile`;
23494
- const profileResponse = await fetch(agentProfileUrl);
24042
+ const profileResponse = await fetch(agentProfileUrl, {
24043
+ headers: attachClientVersionHeader(),
24044
+ });
23495
24045
  // <- TODO: [🐱‍🚀] What about closed-source agents?
23496
24046
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
23497
24047
  if (!profileResponse.ok) {
@@ -23592,6 +24142,7 @@
23592
24142
  }
23593
24143
  const response = await fetch(`${this.agentUrl}/api/voice`, {
23594
24144
  method: 'POST',
24145
+ headers: attachClientVersionHeader(),
23595
24146
  body: formData,
23596
24147
  });
23597
24148
  if (!response.ok) {
@@ -23621,13 +24172,14 @@
23621
24172
  const chatPrompt = prompt;
23622
24173
  const bookResponse = await fetch(`${this.agentUrl}/api/chat`, {
23623
24174
  method: 'POST',
23624
- headers: {
24175
+ headers: attachClientVersionHeader({
23625
24176
  'Content-Type': 'application/json',
23626
- },
24177
+ }),
23627
24178
  body: JSON.stringify({
23628
24179
  message: prompt.content,
23629
24180
  thread: chatPrompt.thread,
23630
24181
  attachments: chatPrompt.attachments,
24182
+ parameters: chatPrompt.parameters,
23631
24183
  }),
23632
24184
  });
23633
24185
  // <- TODO: [🐱‍🚀] What about closed-source agents?
@@ -23709,6 +24261,9 @@
23709
24261
  const lines = textChunk.split(/\r?\n/);
23710
24262
  for (const line of lines) {
23711
24263
  const trimmedLine = line.trim();
24264
+ if (trimmedLine === CHAT_STREAM_KEEP_ALIVE_TOKEN) {
24265
+ continue;
24266
+ }
23712
24267
  let isToolCallLine = false;
23713
24268
  if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
23714
24269
  try {