@promptbook/core 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 +1 -1
  32. package/umd/index.umd.js +677 -171
  33. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -28,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.110.0';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.111.0-1';
32
32
  /**
33
33
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
34
34
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -8869,6 +8869,36 @@ function prompt(strings, ...values) {
8869
8869
  * Note: [💞] Ignore a discrepancy between file name and entity name
8870
8870
  */
8871
8871
 
8872
+ /**
8873
+ * HTTP header used by Promptbook clients to advertise their release version.
8874
+ *
8875
+ * @public exported from `@promptbook/utils`
8876
+ */
8877
+ const CLIENT_VERSION_HEADER = 'x-promptbook-client-version';
8878
+ /**
8879
+ * The latest client (engine) version that the server expects.
8880
+ *
8881
+ * @public exported from `@promptbook/utils`
8882
+ */
8883
+ const CLIENT_LATEST_VERSION = PROMPTBOOK_ENGINE_VERSION;
8884
+ /**
8885
+ * Creates a headers object that includes the client version header.
8886
+ *
8887
+ * @param headers - Optional base headers to clone.
8888
+ * @returns New headers object augmented with `CLIENT_VERSION_HEADER`.
8889
+ *
8890
+ * @public exported from `@promptbook/utils`
8891
+ */
8892
+ function attachClientVersionHeader(headers) {
8893
+ return {
8894
+ ...(headers !== null && headers !== void 0 ? headers : {}),
8895
+ [CLIENT_VERSION_HEADER]: CLIENT_LATEST_VERSION,
8896
+ };
8897
+ }
8898
+ /**
8899
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8900
+ */
8901
+
8872
8902
  /**
8873
8903
  * Detects if the code is running in a browser environment in main thread (Not in a web worker)
8874
8904
  *
@@ -10932,28 +10962,14 @@ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
10932
10962
  * Note: [💞] Ignore a discrepancy between file name and entity name
10933
10963
  */
10934
10964
 
10935
- /**
10936
- * @@@
10937
- *
10938
- * @private thing of inline knowledge
10939
- */
10965
+ /** @private The default base name for inline knowledge files when the content lacks identifying text */
10940
10966
  const INLINE_KNOWLEDGE_BASE_NAME = 'inline-knowledge';
10941
- /**
10942
- * @@@
10943
- *
10944
- * @private thing of inline knowledge
10945
- */
10967
+ /** @private The default file extension used for inline knowledge uploads */
10946
10968
  const INLINE_KNOWLEDGE_EXTENSION = '.txt';
10947
- /**
10948
- * @@@
10949
- *
10950
- * @private thing of inline knowledge
10951
- */
10969
+ /** @private Prefix that identifies base64 data URLs */
10952
10970
  const DATA_URL_PREFIX = 'data:';
10953
10971
  /**
10954
- * @@@
10955
- *
10956
- * @private thing of inline knowledge
10972
+ * @private Retrieves the first meaningful line from the inline content.
10957
10973
  */
10958
10974
  function getFirstNonEmptyLine(content) {
10959
10975
  const lines = content.split(/\r?\n/);
@@ -10966,9 +10982,7 @@ function getFirstNonEmptyLine(content) {
10966
10982
  return null;
10967
10983
  }
10968
10984
  /**
10969
- * @@@
10970
- *
10971
- * @private thing of inline knowledge
10985
+ * @private Determines the base file name by normalizing the first non-empty line.
10972
10986
  */
10973
10987
  function deriveBaseFilename(content) {
10974
10988
  const firstLine = getFirstNonEmptyLine(content);
@@ -10979,22 +10993,18 @@ function deriveBaseFilename(content) {
10979
10993
  return normalized || INLINE_KNOWLEDGE_BASE_NAME;
10980
10994
  }
10981
10995
  /**
10982
- * Creates a data URL that represents the inline knowledge content as a text file.
10983
- *
10984
- * @private thing of inline knowledge
10996
+ * @private Converts inline knowledge into the internal metadata form used for uploads.
10985
10997
  */
10986
10998
  function createInlineKnowledgeSourceFile(content) {
10987
10999
  const trimmedContent = content.trim();
10988
11000
  const baseName = deriveBaseFilename(trimmedContent);
10989
11001
  const filename = `${baseName}${INLINE_KNOWLEDGE_EXTENSION}`;
10990
11002
  const mimeType = 'text/plain';
10991
- const base64 = Buffer.from(trimmedContent, 'utf-8').toString('base64');
10992
- const encodedFilename = encodeURIComponent(filename);
10993
- const url = `${DATA_URL_PREFIX}${mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
11003
+ const buffer = Buffer.from(trimmedContent, 'utf-8');
10994
11004
  return {
10995
11005
  filename,
10996
11006
  mimeType,
10997
- url,
11007
+ buffer,
10998
11008
  };
10999
11009
  }
11000
11010
  /**
@@ -11005,10 +11015,18 @@ function createInlineKnowledgeSourceFile(content) {
11005
11015
  function isDataUrlKnowledgeSource(source) {
11006
11016
  return typeof source === 'string' && source.startsWith(DATA_URL_PREFIX);
11007
11017
  }
11018
+ /**
11019
+ * @private Converts a stored inline knowledge file into a data URL for backwards compatibility.
11020
+ */
11021
+ function inlineKnowledgeSourceToDataUrl(source) {
11022
+ const base64 = source.buffer.toString('base64');
11023
+ const encodedFilename = encodeURIComponent(source.filename);
11024
+ return `${DATA_URL_PREFIX}${source.mimeType};name=${encodedFilename};charset=utf-8;base64,${base64}`;
11025
+ }
11008
11026
  /**
11009
11027
  * Parses a data URL-based knowledge source into its raw buffer, filename, and MIME type.
11010
11028
  *
11011
- * @private thing of inline knowledge
11029
+ * @private utility of inline knowledge processing
11012
11030
  */
11013
11031
  function parseDataUrlKnowledgeSource(source) {
11014
11032
  if (!isDataUrlKnowledgeSource(source)) {
@@ -11141,6 +11159,7 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
11141
11159
  `);
11142
11160
  }
11143
11161
  applyToAgentModelRequirements(requirements, content) {
11162
+ var _a;
11144
11163
  const trimmedContent = content.trim();
11145
11164
  if (!trimmedContent) {
11146
11165
  return requirements;
@@ -11161,9 +11180,13 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
11161
11180
  }
11162
11181
  else {
11163
11182
  const inlineSource = createInlineKnowledgeSourceFile(trimmedContent);
11183
+ const existingInlineSources = (((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.inlineKnowledgeSources) || []).slice();
11164
11184
  const updatedRequirements = {
11165
11185
  ...requirements,
11166
- knowledgeSources: [...(requirements.knowledgeSources || []), inlineSource.url],
11186
+ _metadata: {
11187
+ ...requirements._metadata,
11188
+ inlineKnowledgeSources: [...existingInlineSources, inlineSource],
11189
+ },
11167
11190
  };
11168
11191
  const knowledgeInfo = `Knowledge Source Inline: ${inlineSource.filename} (derived from inline content and processed for retrieval during chat)`;
11169
11192
  return this.appendToSystemMessage(updatedRequirements, knowledgeInfo, '\n\n');
@@ -11245,6 +11268,237 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
11245
11268
  * Note: [💞] Ignore a discrepancy between file name and entity name
11246
11269
  */
11247
11270
 
11271
+ /**
11272
+ * @@@
11273
+ *
11274
+ * @private utility for commitments
11275
+ */
11276
+ function formatOptionalInstructionBlock(label, content) {
11277
+ const trimmedContent = spaceTrim$1(content);
11278
+ if (!trimmedContent) {
11279
+ return '';
11280
+ }
11281
+ return spaceTrim$1((block) => `
11282
+ - ${label}:
11283
+ ${block(trimmedContent
11284
+ .split(/\r?\n/)
11285
+ .map((line) => `- ${line}`)
11286
+ .join('\n'))}
11287
+ `);
11288
+ }
11289
+
11290
+ /**
11291
+ * Prompt parameter key used to pass hidden runtime context to tool execution.
11292
+ *
11293
+ * @private internal runtime wiring for commitment tools
11294
+ */
11295
+ const TOOL_RUNTIME_CONTEXT_PARAMETER = 'promptbookToolRuntimeContext';
11296
+ /**
11297
+ * Hidden argument key used to pass runtime context into individual tool calls.
11298
+ *
11299
+ * @private internal runtime wiring for commitment tools
11300
+ */
11301
+ const TOOL_RUNTIME_CONTEXT_ARGUMENT = '__promptbookToolRuntimeContext';
11302
+ /**
11303
+ * Parses unknown runtime context payload into a normalized object.
11304
+ *
11305
+ * @private internal runtime wiring for commitment tools
11306
+ */
11307
+ function parseToolRuntimeContext(rawValue) {
11308
+ if (!rawValue) {
11309
+ return null;
11310
+ }
11311
+ let parsed = rawValue;
11312
+ if (typeof rawValue === 'string') {
11313
+ try {
11314
+ parsed = JSON.parse(rawValue);
11315
+ }
11316
+ catch (_a) {
11317
+ return null;
11318
+ }
11319
+ }
11320
+ if (!parsed || typeof parsed !== 'object') {
11321
+ return null;
11322
+ }
11323
+ return parsed;
11324
+ }
11325
+ /**
11326
+ * Reads runtime context attached to tool call arguments.
11327
+ *
11328
+ * @private internal runtime wiring for commitment tools
11329
+ */
11330
+ function readToolRuntimeContextFromToolArgs(args) {
11331
+ return parseToolRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]);
11332
+ }
11333
+ /**
11334
+ * Serializes runtime context for prompt parameters.
11335
+ *
11336
+ * @private internal runtime wiring for commitment tools
11337
+ */
11338
+ function serializeToolRuntimeContext(context) {
11339
+ return JSON.stringify(context);
11340
+ }
11341
+ /**
11342
+ * Note: [💞] Ignore a discrepancy between file name and entity name
11343
+ */
11344
+
11345
+ /**
11346
+ * Tool name used to retrieve persisted user memory.
11347
+ *
11348
+ * @private internal MEMORY commitment constant
11349
+ */
11350
+ const RETRIEVE_USER_MEMORY_TOOL_NAME = 'retrieve_user_memory';
11351
+ /**
11352
+ * Tool name used to store persisted user memory.
11353
+ *
11354
+ * @private internal MEMORY commitment constant
11355
+ */
11356
+ const STORE_USER_MEMORY_TOOL_NAME = 'store_user_memory';
11357
+ const UPDATE_USER_MEMORY_TOOL_NAME = 'update_user_memory';
11358
+ const DELETE_USER_MEMORY_TOOL_NAME = 'delete_user_memory';
11359
+ /**
11360
+ * Resolves runtime context from hidden tool arguments.
11361
+ *
11362
+ * @private utility of MEMORY commitment
11363
+ */
11364
+ function resolveMemoryRuntimeContext(args) {
11365
+ const runtimeContext = readToolRuntimeContextFromToolArgs(args);
11366
+ const memoryContext = runtimeContext === null || runtimeContext === void 0 ? void 0 : runtimeContext.memory;
11367
+ return {
11368
+ enabled: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.enabled) === true,
11369
+ userId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.userId,
11370
+ username: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.username,
11371
+ agentId: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentId,
11372
+ agentName: memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.agentName,
11373
+ isTeamConversation: (memoryContext === null || memoryContext === void 0 ? void 0 : memoryContext.isTeamConversation) === true,
11374
+ };
11375
+ }
11376
+ /**
11377
+ * Builds a disabled memory-tool response payload.
11378
+ *
11379
+ * @private utility of MEMORY commitment
11380
+ */
11381
+ function createDisabledMemoryResult(action, message) {
11382
+ if (action === 'retrieve') {
11383
+ return {
11384
+ action,
11385
+ status: 'disabled',
11386
+ memories: [],
11387
+ message,
11388
+ };
11389
+ }
11390
+ if (action === 'store') {
11391
+ return {
11392
+ action,
11393
+ status: 'disabled',
11394
+ message,
11395
+ };
11396
+ }
11397
+ if (action === 'update') {
11398
+ return {
11399
+ action,
11400
+ status: 'disabled',
11401
+ message,
11402
+ };
11403
+ }
11404
+ if (action === 'delete') {
11405
+ return {
11406
+ action,
11407
+ status: 'disabled',
11408
+ message,
11409
+ };
11410
+ }
11411
+ throw new Error(`Unsupported memory tool action: ${action}`);
11412
+ }
11413
+ /**
11414
+ * Gets the runtime adapter and returns a disabled result when unavailable.
11415
+ *
11416
+ * @private utility of MEMORY commitment
11417
+ */
11418
+ function getRuntimeAdapterOrDisabledResult(action, runtimeContext) {
11419
+ if (!runtimeContext.enabled || runtimeContext.isTeamConversation) {
11420
+ return {
11421
+ adapter: null,
11422
+ disabledResult: createDisabledMemoryResult(action, runtimeContext.isTeamConversation
11423
+ ? 'Memory is disabled for TEAM conversations.'
11424
+ : 'Memory is disabled for unauthenticated users.'),
11425
+ };
11426
+ }
11427
+ {
11428
+ return {
11429
+ adapter: null,
11430
+ disabledResult: createDisabledMemoryResult(action, 'Memory runtime is not available in this environment.'),
11431
+ };
11432
+ }
11433
+ }
11434
+ /**
11435
+ * Parses retrieve memory arguments.
11436
+ *
11437
+ * @private utility of MEMORY commitment
11438
+ */
11439
+ function parseRetrieveMemoryArgs(args) {
11440
+ const query = typeof args.query === 'string' ? args.query.trim() : undefined;
11441
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? Math.floor(args.limit) : undefined;
11442
+ return {
11443
+ query: query && query.length > 0 ? query : undefined,
11444
+ limit: limit && limit > 0 ? Math.min(limit, 20) : undefined,
11445
+ };
11446
+ }
11447
+ /**
11448
+ * Parses store memory arguments.
11449
+ *
11450
+ * @private utility of MEMORY commitment
11451
+ */
11452
+ function parseStoreMemoryArgs(args) {
11453
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
11454
+ if (!content) {
11455
+ throw new Error('Memory content is required.');
11456
+ }
11457
+ return {
11458
+ content,
11459
+ isGlobal: args.isGlobal === true,
11460
+ };
11461
+ }
11462
+ /**
11463
+ * Parses a memory identifier argument shared across MEMORY tools.
11464
+ *
11465
+ * @private utility of MEMORY commitment
11466
+ */
11467
+ function parseMemoryIdArg(value) {
11468
+ const memoryId = typeof value === 'string' ? value.trim() : '';
11469
+ if (!memoryId) {
11470
+ throw new Error('Memory id is required.');
11471
+ }
11472
+ return memoryId;
11473
+ }
11474
+ /**
11475
+ * Parses update memory arguments.
11476
+ *
11477
+ * @private utility of MEMORY commitment
11478
+ */
11479
+ function parseUpdateMemoryArgs(args) {
11480
+ const memoryId = parseMemoryIdArg(args.memoryId);
11481
+ const content = typeof args.content === 'string' ? args.content.trim() : '';
11482
+ if (!content) {
11483
+ throw new Error('Memory content is required.');
11484
+ }
11485
+ const isGlobal = typeof args.isGlobal === 'boolean' ? args.isGlobal : undefined;
11486
+ return {
11487
+ memoryId,
11488
+ content,
11489
+ isGlobal,
11490
+ };
11491
+ }
11492
+ /**
11493
+ * Parses delete memory arguments.
11494
+ *
11495
+ * @private utility of MEMORY commitment
11496
+ */
11497
+ function parseDeleteMemoryArgs(args) {
11498
+ return {
11499
+ memoryId: parseMemoryIdArg(args.memoryId),
11500
+ };
11501
+ }
11248
11502
  /**
11249
11503
  * MEMORY commitment definition
11250
11504
  *
@@ -11266,6 +11520,9 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
11266
11520
  constructor(type = 'MEMORY') {
11267
11521
  super(type);
11268
11522
  }
11523
+ get requiresContent() {
11524
+ return false;
11525
+ }
11269
11526
  /**
11270
11527
  * Short one-line description of MEMORY.
11271
11528
  */
@@ -11285,21 +11542,14 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
11285
11542
  return spaceTrim$1(`
11286
11543
  # ${this.type}
11287
11544
 
11288
- 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.
11545
+ Enables persistent user memory for the current agent. The memory is stored by the runtime and can be retrieved in future conversations.
11289
11546
 
11290
11547
  ## Key aspects
11291
11548
 
11292
- - Both terms work identically and can be used interchangeably.
11293
- - Focuses on user-specific information and interaction history.
11294
- - Helps personalize responses based on past interactions.
11295
- - Maintains continuity across conversations.
11296
-
11297
- ## Differences from KNOWLEDGE
11298
-
11299
- - \`KNOWLEDGE\` is for domain expertise and factual information
11300
- - \`MEMORY\` is for user-specific context and preferences
11301
- - \`MEMORY\` creates more personalized interactions
11302
- - \`MEMORY\` often includes temporal or preference-based information
11549
+ - Both \`MEMORY\` and \`MEMORIES\` work identically.
11550
+ - Stores user-specific details through runtime tools.
11551
+ - Retrieves relevant memories for personalized responses.
11552
+ - Supports optional extra instructions in the commitment content.
11303
11553
 
11304
11554
  ## Examples
11305
11555
 
@@ -11307,10 +11557,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
11307
11557
  Personal Assistant
11308
11558
 
11309
11559
  PERSONA You are a personal productivity assistant
11310
- MEMORY User is a software developer working in JavaScript/React
11311
- MEMORY User prefers morning work sessions and afternoon meetings
11312
- MEMORY Previously helped with project planning for mobile apps
11313
- MEMORY User timezone: UTC-8 (Pacific Time)
11560
+ MEMORY Remember user projects and long-term preferences.
11314
11561
  GOAL Help optimize daily productivity and workflow
11315
11562
  \`\`\`
11316
11563
 
@@ -11318,10 +11565,7 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
11318
11565
  Learning Companion
11319
11566
 
11320
11567
  PERSONA You are an educational companion for programming students
11321
- MEMORY Student is learning Python as their first programming language
11322
- MEMORY Previous topics covered: variables, loops, functions
11323
- MEMORY Student learns best with practical examples and exercises
11324
- MEMORY Last session: working on list comprehensions
11568
+ MEMORY Remember only the student's learning progress and preferred study style.
11325
11569
  GOAL Provide progressive learning experiences tailored to student's pace
11326
11570
  \`\`\`
11327
11571
 
@@ -11329,23 +11573,245 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
11329
11573
  Customer Support Agent
11330
11574
 
11331
11575
  PERSONA You are a customer support representative
11332
- MEMORY Customer has premium subscription since 2023
11333
- MEMORY Previous issue: billing question resolved last month
11334
- MEMORY Customer prefers email communication over phone calls
11335
- MEMORY Account shows frequent use of advanced features
11576
+ MEMORY Remember only important support history and communication preferences.
11336
11577
  GOAL Provide personalized support based on customer history
11337
11578
  \`\`\`
11338
11579
  `);
11339
11580
  }
11340
11581
  applyToAgentModelRequirements(requirements, content) {
11341
- const trimmedContent = content.trim();
11342
- if (!trimmedContent) {
11343
- return requirements;
11582
+ const extraInstructions = formatOptionalInstructionBlock('Memory instructions', content);
11583
+ const existingTools = requirements.tools || [];
11584
+ const tools = [...existingTools];
11585
+ if (!tools.some((tool) => tool.name === RETRIEVE_USER_MEMORY_TOOL_NAME)) {
11586
+ tools.push({
11587
+ name: RETRIEVE_USER_MEMORY_TOOL_NAME,
11588
+ description: spaceTrim$1(`
11589
+ Retrieve previously stored user memories relevant to the current conversation.
11590
+ Use this before responding when user context can improve the answer.
11591
+ `),
11592
+ parameters: {
11593
+ type: 'object',
11594
+ properties: {
11595
+ query: {
11596
+ type: 'string',
11597
+ description: 'Optional query used to filter relevant memories.',
11598
+ },
11599
+ limit: {
11600
+ type: 'integer',
11601
+ description: 'Optional maximum number of memories to return (default 5, max 20).',
11602
+ },
11603
+ },
11604
+ },
11605
+ });
11606
+ }
11607
+ if (!tools.some((tool) => tool.name === STORE_USER_MEMORY_TOOL_NAME)) {
11608
+ tools.push({
11609
+ name: STORE_USER_MEMORY_TOOL_NAME,
11610
+ description: spaceTrim$1(`
11611
+ Store a durable user memory that should be remembered in future conversations.
11612
+ Store only stable and useful user-specific facts or preferences.
11613
+ `),
11614
+ parameters: {
11615
+ type: 'object',
11616
+ properties: {
11617
+ content: {
11618
+ type: 'string',
11619
+ description: 'Memory text to store.',
11620
+ },
11621
+ isGlobal: {
11622
+ type: 'boolean',
11623
+ description: 'Set true to make this memory global across all user agents.',
11624
+ },
11625
+ },
11626
+ required: ['content'],
11627
+ },
11628
+ });
11629
+ }
11630
+ if (!tools.some((tool) => tool.name === UPDATE_USER_MEMORY_TOOL_NAME)) {
11631
+ tools.push({
11632
+ name: UPDATE_USER_MEMORY_TOOL_NAME,
11633
+ description: spaceTrim$1(`
11634
+ Update an existing user memory after retrieving it, so the stored fact stays accurate.
11635
+ Always pass the memory id you retrieved along with the new content.
11636
+ `),
11637
+ parameters: {
11638
+ type: 'object',
11639
+ properties: {
11640
+ memoryId: {
11641
+ type: 'string',
11642
+ description: 'Unique identifier of the memory entry to update.',
11643
+ },
11644
+ content: {
11645
+ type: 'string',
11646
+ description: 'Updated memory text.',
11647
+ },
11648
+ isGlobal: {
11649
+ type: 'boolean',
11650
+ description: 'Set true to keep the fact global; omit or false to keep it agent-scoped.',
11651
+ },
11652
+ },
11653
+ required: ['memoryId', 'content'],
11654
+ },
11655
+ });
11656
+ }
11657
+ if (!tools.some((tool) => tool.name === DELETE_USER_MEMORY_TOOL_NAME)) {
11658
+ tools.push({
11659
+ name: DELETE_USER_MEMORY_TOOL_NAME,
11660
+ description: spaceTrim$1(`
11661
+ Delete a user memory that is no longer relevant. Deletions are soft so the record is hidden from future queries.
11662
+ `),
11663
+ parameters: {
11664
+ type: 'object',
11665
+ properties: {
11666
+ memoryId: {
11667
+ type: 'string',
11668
+ description: 'Unique identifier of the memory entry to delete.',
11669
+ },
11670
+ },
11671
+ required: ['memoryId'],
11672
+ },
11673
+ });
11344
11674
  }
11345
- // Create memory section for system message
11346
- const memorySection = `Memory: ${trimmedContent}`;
11347
- // Memory information is contextual and should be included in the system message
11348
- return this.appendToSystemMessage(requirements, memorySection, '\n\n');
11675
+ return this.appendToSystemMessage({
11676
+ ...requirements,
11677
+ tools,
11678
+ _metadata: {
11679
+ ...requirements._metadata,
11680
+ useMemory: content || true,
11681
+ },
11682
+ }, spaceTrim$1((block) => `
11683
+ Memory:
11684
+ - Prefer storing agent-scoped memories; only make them global when the fact should apply across all your agents.
11685
+ - You can use persistent user memory tools.
11686
+ - Use "${RETRIEVE_USER_MEMORY_TOOL_NAME}" to load relevant memory before answering.
11687
+ - Use "${STORE_USER_MEMORY_TOOL_NAME}" to save stable user-specific facts that improve future help.
11688
+ - Use "${UPDATE_USER_MEMORY_TOOL_NAME}" to refresh an existing memory when the content changes.
11689
+ - Use "${DELETE_USER_MEMORY_TOOL_NAME}" to delete memories that are no longer accurate (deletions are soft and hidden from future queries).
11690
+ - Store concise memory items and avoid duplicates.
11691
+ - Never claim memory was saved or loaded unless the tool confirms it.
11692
+ ${block(extraInstructions)}
11693
+ `));
11694
+ }
11695
+ /**
11696
+ * Gets human-readable titles for MEMORY tool functions.
11697
+ */
11698
+ getToolTitles() {
11699
+ return {
11700
+ [RETRIEVE_USER_MEMORY_TOOL_NAME]: 'User memory',
11701
+ [STORE_USER_MEMORY_TOOL_NAME]: 'Store user memory',
11702
+ [UPDATE_USER_MEMORY_TOOL_NAME]: 'Update user memory',
11703
+ [DELETE_USER_MEMORY_TOOL_NAME]: 'Delete user memory',
11704
+ };
11705
+ }
11706
+ /**
11707
+ * Gets MEMORY tool function implementations.
11708
+ */
11709
+ getToolFunctions() {
11710
+ return {
11711
+ async [RETRIEVE_USER_MEMORY_TOOL_NAME](args) {
11712
+ const runtimeContext = resolveMemoryRuntimeContext(args);
11713
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('retrieve', runtimeContext);
11714
+ if (!adapter || disabledResult) {
11715
+ return JSON.stringify(disabledResult);
11716
+ }
11717
+ const parsedArgs = parseRetrieveMemoryArgs(args);
11718
+ try {
11719
+ const memories = await adapter.retrieveMemories(parsedArgs, runtimeContext);
11720
+ const result = {
11721
+ action: 'retrieve',
11722
+ status: 'ok',
11723
+ query: parsedArgs.query,
11724
+ memories,
11725
+ };
11726
+ return JSON.stringify(result);
11727
+ }
11728
+ catch (error) {
11729
+ const result = {
11730
+ action: 'retrieve',
11731
+ status: 'error',
11732
+ query: parsedArgs.query,
11733
+ memories: [],
11734
+ message: error instanceof Error ? error.message : String(error),
11735
+ };
11736
+ return JSON.stringify(result);
11737
+ }
11738
+ },
11739
+ async [STORE_USER_MEMORY_TOOL_NAME](args) {
11740
+ const runtimeContext = resolveMemoryRuntimeContext(args);
11741
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('store', runtimeContext);
11742
+ if (!adapter || disabledResult) {
11743
+ return JSON.stringify(disabledResult);
11744
+ }
11745
+ try {
11746
+ const parsedArgs = parseStoreMemoryArgs(args);
11747
+ const memory = await adapter.storeMemory(parsedArgs, runtimeContext);
11748
+ const result = {
11749
+ action: 'store',
11750
+ status: 'stored',
11751
+ memory,
11752
+ };
11753
+ return JSON.stringify(result);
11754
+ }
11755
+ catch (error) {
11756
+ const result = {
11757
+ action: 'store',
11758
+ status: 'error',
11759
+ message: error instanceof Error ? error.message : String(error),
11760
+ };
11761
+ return JSON.stringify(result);
11762
+ }
11763
+ },
11764
+ async [UPDATE_USER_MEMORY_TOOL_NAME](args) {
11765
+ const runtimeContext = resolveMemoryRuntimeContext(args);
11766
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('update', runtimeContext);
11767
+ if (!adapter || disabledResult) {
11768
+ return JSON.stringify(disabledResult);
11769
+ }
11770
+ try {
11771
+ const parsedArgs = parseUpdateMemoryArgs(args);
11772
+ const memory = await adapter.updateMemory(parsedArgs, runtimeContext);
11773
+ const result = {
11774
+ action: 'update',
11775
+ status: 'updated',
11776
+ memory,
11777
+ };
11778
+ return JSON.stringify(result);
11779
+ }
11780
+ catch (error) {
11781
+ const result = {
11782
+ action: 'update',
11783
+ status: 'error',
11784
+ message: error instanceof Error ? error.message : String(error),
11785
+ };
11786
+ return JSON.stringify(result);
11787
+ }
11788
+ },
11789
+ async [DELETE_USER_MEMORY_TOOL_NAME](args) {
11790
+ const runtimeContext = resolveMemoryRuntimeContext(args);
11791
+ const { adapter, disabledResult } = getRuntimeAdapterOrDisabledResult('delete', runtimeContext);
11792
+ if (!adapter || disabledResult) {
11793
+ return JSON.stringify(disabledResult);
11794
+ }
11795
+ try {
11796
+ const parsedArgs = parseDeleteMemoryArgs(args);
11797
+ const deleted = await adapter.deleteMemory(parsedArgs, runtimeContext);
11798
+ const result = {
11799
+ action: 'delete',
11800
+ status: 'deleted',
11801
+ memoryId: deleted.id,
11802
+ };
11803
+ return JSON.stringify(result);
11804
+ }
11805
+ catch (error) {
11806
+ const result = {
11807
+ action: 'delete',
11808
+ status: 'error',
11809
+ message: error instanceof Error ? error.message : String(error),
11810
+ };
11811
+ return JSON.stringify(result);
11812
+ }
11813
+ },
11814
+ };
11349
11815
  }
11350
11816
  }
11351
11817
  /**
@@ -13458,14 +13924,30 @@ function buildTeammateRequest(message, context) {
13458
13924
  /**
13459
13925
  * Builds a minimal chat prompt for teammate calls.
13460
13926
  */
13461
- function buildTeammatePrompt(request) {
13927
+ function buildTeammatePrompt(request, runtimeContext) {
13462
13928
  return {
13463
13929
  title: 'Teammate consultation',
13464
13930
  modelRequirements: {
13465
13931
  modelVariant: 'CHAT',
13466
13932
  },
13467
13933
  content: request,
13468
- parameters: {},
13934
+ parameters: {
13935
+ [TOOL_RUNTIME_CONTEXT_PARAMETER]: serializeToolRuntimeContext(runtimeContext),
13936
+ },
13937
+ };
13938
+ }
13939
+ /**
13940
+ * Creates teammate runtime context and marks conversation as team-only memory-disabled.
13941
+ */
13942
+ function createTeamConversationRuntimeContext(value) {
13943
+ const runtimeContext = parseToolRuntimeContext(value) || {};
13944
+ return {
13945
+ ...runtimeContext,
13946
+ memory: {
13947
+ ...(runtimeContext.memory || {}),
13948
+ enabled: false,
13949
+ isTeamConversation: true,
13950
+ },
13469
13951
  };
13470
13952
  }
13471
13953
  /**
@@ -13509,7 +13991,7 @@ function createTeamToolFunction(entry) {
13509
13991
  let toolCalls;
13510
13992
  try {
13511
13993
  const remoteAgent = await getRemoteTeammateAgent(entry.teammate.url);
13512
- const prompt = buildTeammatePrompt(request);
13994
+ const prompt = buildTeammatePrompt(request, createTeamConversationRuntimeContext(args[TOOL_RUNTIME_CONTEXT_ARGUMENT]));
13513
13995
  const teammateResult = await remoteAgent.callChatModel(prompt);
13514
13996
  response = teammateResult.content || '';
13515
13997
  toolCalls =
@@ -14059,25 +14541,6 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
14059
14541
  * Note: [💞] Ignore a discrepancy between file name and entity name
14060
14542
  */
14061
14543
 
14062
- /**
14063
- * @@@
14064
- *
14065
- * @private utility for commitments
14066
- */
14067
- function formatOptionalInstructionBlock(label, content) {
14068
- const trimmedContent = spaceTrim$1(content);
14069
- if (!trimmedContent) {
14070
- return '';
14071
- }
14072
- return spaceTrim$1((block) => `
14073
- - ${label}:
14074
- ${block(trimmedContent
14075
- .split(/\r?\n/)
14076
- .map((line) => `- ${line}`)
14077
- .join('\n'))}
14078
- `);
14079
- }
14080
-
14081
14544
  /**
14082
14545
  * Client-side safe wrapper for sending emails.
14083
14546
  *
@@ -14271,8 +14734,8 @@ class UseEmailCommitmentDefinition extends BaseCommitmentDefinition {
14271
14734
  /**
14272
14735
  * USE IMAGE GENERATOR commitment definition
14273
14736
  *
14274
- * The `USE IMAGE GENERATOR` commitment indicates that the agent should utilize an image generation tool
14275
- * to create images based on text prompts.
14737
+ * The `USE IMAGE GENERATOR` commitment indicates that the agent can output
14738
+ * markdown placeholders for UI-driven image generation.
14276
14739
  *
14277
14740
  * Example usage in agent source:
14278
14741
  *
@@ -14287,11 +14750,14 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
14287
14750
  constructor(type = 'USE IMAGE GENERATOR') {
14288
14751
  super(type, ['USE IMAGE GENERATION', 'IMAGE GENERATOR', 'IMAGE GENERATION', 'USE IMAGE']);
14289
14752
  }
14753
+ get requiresContent() {
14754
+ return false;
14755
+ }
14290
14756
  /**
14291
14757
  * Short one-line description of USE IMAGE GENERATOR.
14292
14758
  */
14293
14759
  get description() {
14294
- return 'Enable the agent to use an image generation tool for creating images from text prompts.';
14760
+ return 'Enable the agent to output markdown image placeholders that the UI turns into generated images.';
14295
14761
  }
14296
14762
  /**
14297
14763
  * Icon for this commitment.
@@ -14306,21 +14772,21 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
14306
14772
  return spaceTrim$1(`
14307
14773
  # USE IMAGE GENERATOR
14308
14774
 
14309
- Enables the agent to use an image generation tool to create images based on text prompts.
14775
+ Enables the agent to output markdown image placeholders that trigger image generation in the user interface.
14310
14776
 
14311
14777
  ## Key aspects
14312
14778
 
14313
14779
  - The content following \`USE IMAGE GENERATOR\` is an arbitrary text that the agent should know (e.g. style instructions or safety guidelines).
14314
- - The actual image generation is handled by the agent runtime using LLM execution tools.
14315
- - Allows the agent to generate visual content based on user requests.
14316
- - Returns the URL of the generated image.
14780
+ - The agent does **not** call an image-generation tool directly.
14781
+ - The agent inserts markdown notation: \`![alt](?image-prompt=...)\`.
14782
+ - The user interface detects the notation and generates the image asynchronously.
14317
14783
 
14318
14784
  ## Examples
14319
14785
 
14320
14786
  \`\`\`book
14321
14787
  Visual Artist
14322
14788
 
14323
- PERSONA You are a creative visual artist who can generate images.
14789
+ PERSONA You are a creative visual artist.
14324
14790
  USE IMAGE GENERATOR
14325
14791
  RULE Always describe the generated image to the user.
14326
14792
  \`\`\`
@@ -14330,80 +14796,28 @@ class UseImageGeneratorCommitmentDefinition extends BaseCommitmentDefinition {
14330
14796
 
14331
14797
  PERSONA You are an interior designer who helps users visualize their space.
14332
14798
  USE IMAGE GENERATOR Professional interior design renders.
14333
- ACTION Generate a preview of the designed room.
14799
+ ACTION Add one generated image placeholder whenever a user asks for a visual.
14334
14800
  \`\`\`
14335
14801
  `);
14336
14802
  }
14337
14803
  applyToAgentModelRequirements(requirements, content) {
14338
- // Get existing tools array or create new one
14339
- const existingTools = requirements.tools || [];
14340
- // Add 'generate_image' to tools if not already present
14341
- const updatedTools = existingTools.some((tool) => tool.name === 'generate_image')
14342
- ? existingTools
14343
- : [
14344
- ...existingTools,
14345
- {
14346
- name: 'generate_image',
14347
- description: spaceTrim$1(`
14348
- Generate an image from a text prompt.
14349
- Use this tool when the user asks to create, draw, or generate an image.
14350
- ${!content ? '' : `Style instructions / guidelines: ${content}`}
14351
- `),
14352
- parameters: {
14353
- type: 'object',
14354
- properties: {
14355
- prompt: {
14356
- type: 'string',
14357
- description: 'The detailed description of the image to generate',
14358
- },
14359
- },
14360
- required: ['prompt'],
14361
- },
14362
- },
14363
- ];
14364
- // Return requirements with updated tools and metadata
14804
+ const extraInstructions = formatOptionalInstructionBlock('Image instructions', content);
14365
14805
  return this.appendToSystemMessage({
14366
14806
  ...requirements,
14367
- tools: updatedTools,
14368
14807
  _metadata: {
14369
14808
  ...requirements._metadata,
14370
14809
  useImageGenerator: content || true,
14371
14810
  },
14372
- }, spaceTrim$1(`
14373
- You have access to an image generator. Use it to create images based on user requests.
14374
- When you generate an image, you will receive a URL of the generated image.
14375
- `));
14376
- }
14377
- /**
14378
- * Gets human-readable titles for tool functions provided by this commitment.
14379
- */
14380
- getToolTitles() {
14381
- return {
14382
- generate_image: 'Generate image',
14383
- };
14384
- }
14385
- /**
14386
- * Gets the `generate_image` tool function implementation.
14387
- */
14388
- getToolFunctions() {
14389
- return {
14390
- async generate_image(args, ...extra) {
14391
- console.log('!!!! [Tool] generate_image called', { args });
14392
- const { prompt } = args;
14393
- if (!prompt) {
14394
- throw new Error('Image prompt is required');
14395
- }
14396
- const { llmTools } = extra[0] || {};
14397
- if (!llmTools || !llmTools.callImageGenerationModel) {
14398
- throw new Error('Image generation is not supported by the current model provider');
14399
- }
14400
- const result = await llmTools.callImageGenerationModel({
14401
- content: prompt,
14402
- modelName: 'dall-e-3', // Defaulting to dall-e-3, but this could be configurable
14403
- });
14404
- return result.content;
14405
- },
14406
- };
14811
+ }, spaceTrim$1((block) => `
14812
+ Image generation:
14813
+ - You do not generate images directly and you do not call any image tool.
14814
+ - When the user asks for an image, include markdown notation in your message:
14815
+ \`![<alt text>](?image-prompt=<prompt>)\`
14816
+ - Keep \`<alt text>\` short and descriptive.
14817
+ - Keep \`<prompt>\` detailed so the generated image matches the request.
14818
+ - You can include normal explanatory text before and after the notation.
14819
+ ${block(extraInstructions)}
14820
+ `));
14407
14821
  }
14408
14822
  }
14409
14823
  /**
@@ -15604,6 +16018,7 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
15604
16018
  systemMessage: requirements.systemMessage + '\n\n' + exampleInteractionsContent,
15605
16019
  };
15606
16020
  }
16021
+ requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
15607
16022
  // Remove comment lines (lines starting with #) from the final system message
15608
16023
  // while preserving the original content with comments in metadata
15609
16024
  const cleanedSystemMessage = removeCommentsFromSystemMessage(requirements.systemMessage);
@@ -15612,6 +16027,54 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
15612
16027
  systemMessage: cleanedSystemMessage,
15613
16028
  };
15614
16029
  }
16030
+ /**
16031
+ * @private Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
16032
+ */
16033
+ async function applyPendingInlineKnowledgeSources(requirements, uploader) {
16034
+ var _a;
16035
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
16036
+ if (inlineSources.length === 0) {
16037
+ return requirements;
16038
+ }
16039
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
16040
+ for (const inlineSource of inlineSources) {
16041
+ const url = uploader
16042
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
16043
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
16044
+ knowledgeSources.push(url);
16045
+ }
16046
+ return {
16047
+ ...requirements,
16048
+ knowledgeSources,
16049
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
16050
+ };
16051
+ }
16052
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
16053
+ try {
16054
+ return await uploader(inlineSource);
16055
+ }
16056
+ catch (error) {
16057
+ console.error('[inline-knowledge] Failed to upload inline source', {
16058
+ filename: inlineSource.filename,
16059
+ error,
16060
+ });
16061
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
16062
+ }
16063
+ }
16064
+ function extractInlineKnowledgeSources(metadata) {
16065
+ if (!metadata) {
16066
+ return [];
16067
+ }
16068
+ const value = metadata.inlineKnowledgeSources;
16069
+ return Array.isArray(value) ? value : [];
16070
+ }
16071
+ function stripInlineKnowledgeMetadata(metadata) {
16072
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
16073
+ return metadata;
16074
+ }
16075
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
16076
+ return Object.keys(rest).length > 0 ? rest : undefined;
16077
+ }
15615
16078
  /**
15616
16079
  * Mocked security check for imported files
15617
16080
  *
@@ -22217,6 +22680,28 @@ function mapToolsToOpenAi(tools) {
22217
22680
  }));
22218
22681
  }
22219
22682
 
22683
+ /**
22684
+ * Builds a tool invocation script that injects hidden runtime context into tool args.
22685
+ *
22686
+ * @private utility of OpenAI tool execution wrappers
22687
+ */
22688
+ function buildToolInvocationScript(options) {
22689
+ const { functionName, functionArgsExpression } = options;
22690
+ return `
22691
+ const args = ${functionArgsExpression};
22692
+ const runtimeContextRaw =
22693
+ typeof ${TOOL_RUNTIME_CONTEXT_PARAMETER} === 'undefined'
22694
+ ? undefined
22695
+ : ${TOOL_RUNTIME_CONTEXT_PARAMETER};
22696
+
22697
+ if (runtimeContextRaw !== undefined && args && typeof args === 'object' && !Array.isArray(args)) {
22698
+ args.${TOOL_RUNTIME_CONTEXT_ARGUMENT} = runtimeContextRaw;
22699
+ }
22700
+
22701
+ return await ${functionName}(args);
22702
+ `;
22703
+ }
22704
+
22220
22705
  /**
22221
22706
  * Parses an OpenAI error message to identify which parameter is unsupported
22222
22707
  *
@@ -22570,10 +23055,10 @@ class OpenAiCompatibleExecutionTools {
22570
23055
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
22571
23056
  functionResponse = await scriptTool.execute({
22572
23057
  scriptLanguage: 'javascript',
22573
- script: `
22574
- const args = ${functionArgs};
22575
- return await ${functionName}(args);
22576
- `,
23058
+ script: buildToolInvocationScript({
23059
+ functionName,
23060
+ functionArgsExpression: functionArgs,
23061
+ }),
22577
23062
  parameters: prompt.parameters,
22578
23063
  });
22579
23064
  }
@@ -24275,10 +24760,10 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
24275
24760
  try {
24276
24761
  return await scriptTool.execute({
24277
24762
  scriptLanguage: 'javascript',
24278
- script: `
24279
- const args = ${JSON.stringify(functionArgs)};
24280
- return await ${functionName}(args);
24281
- `,
24763
+ script: buildToolInvocationScript({
24764
+ functionName,
24765
+ functionArgsExpression: JSON.stringify(functionArgs),
24766
+ }),
24282
24767
  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 : {},
24283
24768
  });
24284
24769
  }
@@ -24731,10 +25216,10 @@ class OpenAiAssistantExecutionTools extends OpenAiVectorStoreHandler {
24731
25216
  const scriptTool = scriptTools[0]; // <- TODO: [🧠] Which script tool to use?
24732
25217
  functionResponse = await scriptTool.execute({
24733
25218
  scriptLanguage: 'javascript',
24734
- script: `
24735
- const args = ${JSON.stringify(functionArgs)};
24736
- return await ${functionName}(args);
24737
- `,
25219
+ script: buildToolInvocationScript({
25220
+ functionName,
25221
+ functionArgsExpression: JSON.stringify(functionArgs),
25222
+ }),
24738
25223
  parameters: prompt.parameters,
24739
25224
  });
24740
25225
  if (this.options.isVerbose) {
@@ -26108,6 +26593,20 @@ function getToolCallIdentity(toolCall) {
26108
26593
  return `fallback:${toolCall.name}:${argsKey}`;
26109
26594
  }
26110
26595
 
26596
+ /**
26597
+ * Keep-alive helpers used for streaming chat responses.
26598
+ *
26599
+ * These constants coordinate the signal sent by the Agents Server streaming
26600
+ * endpoint and the parser in the SDK so we can distinguish between
26601
+ * real content and occasional pings.
26602
+ *
26603
+ * @private internal streaming helper for Promptbook chat connections
26604
+ */
26605
+ const CHAT_STREAM_KEEP_ALIVE_TOKEN = 'STREAM_KEEP_ALIVE';
26606
+ /**
26607
+ * Note: [💞] Ignore a discrepancy between file name and entity name
26608
+ */
26609
+
26111
26610
  /**
26112
26611
  * Resolve a remote META IMAGE value into an absolute URL when possible.
26113
26612
  */
@@ -26182,7 +26681,9 @@ class RemoteAgent extends Agent {
26182
26681
  static async connect(options) {
26183
26682
  var _a, _b, _c;
26184
26683
  const agentProfileUrl = `${options.agentUrl}/api/profile`;
26185
- const profileResponse = await fetch(agentProfileUrl);
26684
+ const profileResponse = await fetch(agentProfileUrl, {
26685
+ headers: attachClientVersionHeader(),
26686
+ });
26186
26687
  // <- TODO: [🐱‍🚀] What about closed-source agents?
26187
26688
  // <- TODO: [🐱‍🚀] Maybe use promptbookFetch
26188
26689
  if (!profileResponse.ok) {
@@ -26283,6 +26784,7 @@ class RemoteAgent extends Agent {
26283
26784
  }
26284
26785
  const response = await fetch(`${this.agentUrl}/api/voice`, {
26285
26786
  method: 'POST',
26787
+ headers: attachClientVersionHeader(),
26286
26788
  body: formData,
26287
26789
  });
26288
26790
  if (!response.ok) {
@@ -26312,13 +26814,14 @@ class RemoteAgent extends Agent {
26312
26814
  const chatPrompt = prompt;
26313
26815
  const bookResponse = await fetch(`${this.agentUrl}/api/chat`, {
26314
26816
  method: 'POST',
26315
- headers: {
26817
+ headers: attachClientVersionHeader({
26316
26818
  'Content-Type': 'application/json',
26317
- },
26819
+ }),
26318
26820
  body: JSON.stringify({
26319
26821
  message: prompt.content,
26320
26822
  thread: chatPrompt.thread,
26321
26823
  attachments: chatPrompt.attachments,
26824
+ parameters: chatPrompt.parameters,
26322
26825
  }),
26323
26826
  });
26324
26827
  // <- TODO: [🐱‍🚀] What about closed-source agents?
@@ -26400,6 +26903,9 @@ class RemoteAgent extends Agent {
26400
26903
  const lines = textChunk.split(/\r?\n/);
26401
26904
  for (const line of lines) {
26402
26905
  const trimmedLine = line.trim();
26906
+ if (trimmedLine === CHAT_STREAM_KEEP_ALIVE_TOKEN) {
26907
+ continue;
26908
+ }
26403
26909
  let isToolCallLine = false;
26404
26910
  if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
26405
26911
  try {