@promptbook/browser 0.107.0-0 → 0.110.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 (28) hide show
  1. package/esm/index.es.js +420 -95
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/markdown-utils.index.d.ts +2 -0
  4. package/esm/typings/src/_packages/types.index.d.ts +8 -0
  5. package/esm/typings/src/book-components/AvatarProfile/AvatarProfile/AvatarProfile.d.ts +1 -1
  6. package/esm/typings/src/book-components/Chat/Chat/ChatActionsBar.d.ts +32 -0
  7. package/esm/typings/src/book-components/Chat/Chat/ChatCitationModal.d.ts +21 -0
  8. package/esm/typings/src/book-components/Chat/Chat/ChatInputArea.d.ts +48 -0
  9. package/esm/typings/src/book-components/Chat/Chat/ChatMessageList.d.ts +40 -0
  10. package/esm/typings/src/book-components/Chat/Chat/ChatRatingModal.d.ts +30 -0
  11. package/esm/typings/src/book-components/Chat/Chat/ChatSelfLearningSummary.d.ts +24 -0
  12. package/esm/typings/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +23 -0
  13. package/esm/typings/src/book-components/Chat/Chat/ChatToolCallModalComponents.d.ts +39 -0
  14. package/esm/typings/src/book-components/Chat/hooks/useChatActionsOverlap.d.ts +55 -0
  15. package/esm/typings/src/book-components/Chat/hooks/useChatRatings.d.ts +67 -0
  16. package/esm/typings/src/book-components/Chat/utils/getToolCallChipletInfo.d.ts +7 -0
  17. package/esm/typings/src/book-components/icons/TeacherIcon.d.ts +15 -0
  18. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +18 -1
  19. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +40 -3
  20. package/esm/typings/src/types/ToolCall.d.ts +67 -0
  21. package/esm/typings/src/utils/linguistic-hash/linguisticHash.d.ts +1 -24
  22. package/esm/typings/src/utils/linguistic-hash/linguisticHashWordCount.d.ts +31 -0
  23. package/esm/typings/src/utils/linguistic-hash/linguisticHashWordSelection.d.ts +22 -0
  24. package/esm/typings/src/utils/markdown/humanizeAiTextSources.d.ts +13 -0
  25. package/esm/typings/src/version.d.ts +1 -1
  26. package/package.json +2 -2
  27. package/umd/index.umd.js +420 -95
  28. 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.107.0-0';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.110.0-0';
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
@@ -3587,13 +3587,125 @@ function escapePromptParameterValue(value, options) {
3587
3587
  return value.replace(pattern, '\\$&');
3588
3588
  }
3589
3589
  /**
3590
- * Builds the parameter name used in prompt placeholders.
3590
+ * Builds numeric parameter name used in prompt placeholders.
3591
3591
  *
3592
3592
  * @param index Zero-based parameter index.
3593
3593
  */
3594
- function buildParameterName(index) {
3594
+ function buildNumericParameterName(index) {
3595
3595
  return `${index + 1}`;
3596
3596
  }
3597
+ /**
3598
+ * Builds alphabetic parameter name used in prompt placeholders.
3599
+ *
3600
+ * @param index Zero-based parameter index.
3601
+ */
3602
+ function buildAlphabeticParameterName(index) {
3603
+ const alphabet = 'abcdefghijklmnopqrstuvwxyz';
3604
+ let result = '';
3605
+ let remaining = index;
3606
+ while (remaining >= 0) {
3607
+ result = alphabet[remaining % alphabet.length] + result;
3608
+ remaining = Math.floor(remaining / alphabet.length) - 1;
3609
+ }
3610
+ return result;
3611
+ }
3612
+ /**
3613
+ * Converts a positive integer into a Roman numeral string.
3614
+ *
3615
+ * @param value Positive integer value.
3616
+ */
3617
+ function toRomanNumeral(value) {
3618
+ const romanTable = [
3619
+ { symbol: 'M', value: 1000 },
3620
+ { symbol: 'CM', value: 900 },
3621
+ { symbol: 'D', value: 500 },
3622
+ { symbol: 'CD', value: 400 },
3623
+ { symbol: 'C', value: 100 },
3624
+ { symbol: 'XC', value: 90 },
3625
+ { symbol: 'L', value: 50 },
3626
+ { symbol: 'XL', value: 40 },
3627
+ { symbol: 'X', value: 10 },
3628
+ { symbol: 'IX', value: 9 },
3629
+ { symbol: 'V', value: 5 },
3630
+ { symbol: 'IV', value: 4 },
3631
+ { symbol: 'I', value: 1 },
3632
+ ];
3633
+ let remaining = Math.max(1, Math.floor(value));
3634
+ let result = '';
3635
+ for (const entry of romanTable) {
3636
+ while (remaining >= entry.value) {
3637
+ result += entry.symbol;
3638
+ remaining -= entry.value;
3639
+ }
3640
+ }
3641
+ return result;
3642
+ }
3643
+ /**
3644
+ * Builds Roman numeral parameter name used in prompt placeholders.
3645
+ *
3646
+ * @param index Zero-based parameter index.
3647
+ */
3648
+ function buildRomanParameterName(index) {
3649
+ return toRomanNumeral(index + 1);
3650
+ }
3651
+ /**
3652
+ * Creates a parameter name builder that prefixes another builder.
3653
+ *
3654
+ * @param prefix Prefix to add.
3655
+ * @param builder Base builder to wrap.
3656
+ */
3657
+ function buildPrefixedParameterName(prefix, builder) {
3658
+ return (index) => `${prefix}${builder(index)}`;
3659
+ }
3660
+ /**
3661
+ * Ordered list of strategies for parameter naming.
3662
+ */
3663
+ const PARAMETER_NAME_STRATEGIES = [
3664
+ { buildName: buildNumericParameterName },
3665
+ { buildName: buildAlphabeticParameterName },
3666
+ { buildName: buildRomanParameterName },
3667
+ { buildName: buildPrefixedParameterName('p', buildNumericParameterName) },
3668
+ { buildName: buildPrefixedParameterName('p', buildAlphabeticParameterName) },
3669
+ ];
3670
+ /**
3671
+ * Collects bracketed tokens from parameter values to avoid placeholder collisions.
3672
+ *
3673
+ * @param values Parameter values to scan.
3674
+ */
3675
+ function collectBracketedParameterTokens(values) {
3676
+ const tokens = new Set();
3677
+ for (const value of values) {
3678
+ const pattern = /{(\w+)}/g;
3679
+ let match;
3680
+ while ((match = pattern.exec(value)) !== null) {
3681
+ const token = match[1];
3682
+ if (token) {
3683
+ tokens.add(token);
3684
+ }
3685
+ }
3686
+ }
3687
+ return tokens;
3688
+ }
3689
+ /**
3690
+ * Builds parameter names used in prompt placeholders while avoiding collisions.
3691
+ *
3692
+ * @param values Parameter values to scan for conflicting tokens.
3693
+ */
3694
+ function buildParameterNames(values) {
3695
+ const count = values.length;
3696
+ if (count === 0) {
3697
+ return [];
3698
+ }
3699
+ const conflicts = collectBracketedParameterTokens(values);
3700
+ for (const strategy of PARAMETER_NAME_STRATEGIES) {
3701
+ const names = Array.from({ length: count }, (_, index) => strategy.buildName(index));
3702
+ const hasConflict = names.some((name) => conflicts.has(name));
3703
+ if (!hasConflict) {
3704
+ return names;
3705
+ }
3706
+ }
3707
+ return Array.from({ length: count }, (_, index) => `${REPLACING_NONCE}${index + 1}`);
3708
+ }
3597
3709
  /**
3598
3710
  * Formats the placeholder used in the prompt body for a parameter.
3599
3711
  *
@@ -3648,26 +3760,40 @@ function prompt(strings, ...values) {
3648
3760
  return new PromptString(spaceTrim$2(strings.join('')));
3649
3761
  }
3650
3762
  const stringsWithHiddenParameters = strings.map((stringsItem) => hideBrackets(stringsItem));
3651
- const parameterEntries = values.map((value, index) => {
3652
- const name = buildParameterName(index);
3763
+ const parameterMetadata = values.map((value) => {
3653
3764
  const isPrompt = isPromptString(value);
3654
3765
  const stringValue = isPrompt ? value.toString() : valueToString(value);
3655
3766
  const isInline = isPrompt ? true : shouldInlineParameterValue(stringValue);
3656
3767
  const jsonValue = !isPrompt && !isInline ? normalizeJsonString(stringValue) : null;
3768
+ return { isPrompt, stringValue, isInline, jsonValue };
3769
+ });
3770
+ const parameterNames = buildParameterNames(parameterMetadata.map((entry) => entry.stringValue));
3771
+ const parameterEntries = parameterMetadata.map((entry, index) => {
3772
+ var _a;
3773
+ const name = (_a = parameterNames[index]) !== null && _a !== void 0 ? _a : buildNumericParameterName(index);
3657
3774
  const promptMarker = `${REPLACING_NONCE}prompt-${index}`;
3658
3775
  const parameterMarker = `${REPLACING_NONCE}parameter-${index}`;
3659
- const templateValue = isPrompt
3776
+ const templateValue = entry.isPrompt
3660
3777
  ? promptMarker
3661
- : isInline
3662
- ? escapePromptParameterValue(stringValue, { includeBraces: false })
3778
+ : entry.isInline
3779
+ ? escapePromptParameterValue(entry.stringValue, { includeBraces: false })
3663
3780
  : parameterMarker;
3664
- return { name, stringValue, jsonValue, isPrompt, isInline, promptMarker, parameterMarker, templateValue };
3781
+ return {
3782
+ name,
3783
+ stringValue: entry.stringValue,
3784
+ jsonValue: entry.jsonValue,
3785
+ isPrompt: entry.isPrompt,
3786
+ isInline: entry.isInline,
3787
+ promptMarker,
3788
+ parameterMarker,
3789
+ templateValue,
3790
+ };
3665
3791
  });
3666
3792
  const parameters = Object.fromEntries(parameterEntries.map((entry) => [entry.name, entry.templateValue]));
3667
- const parameterNames = parameterEntries.map((entry) => entry.name);
3793
+ const parameterNamesOrdered = parameterEntries.map((entry) => entry.name);
3668
3794
  // Combine strings and values
3669
3795
  let pipelineString = stringsWithHiddenParameters.reduce((result, stringsItem, i) => {
3670
- const parameterName = parameterNames[i];
3796
+ const parameterName = parameterNamesOrdered[i];
3671
3797
  return parameterName === undefined
3672
3798
  ? `${result}${stringsItem}`
3673
3799
  : `${result}${stringsItem}${formatParameterPlaceholder(parameterName)}`;
@@ -3680,7 +3806,7 @@ function prompt(strings, ...values) {
3680
3806
  if (!(error instanceof PipelineExecutionError)) {
3681
3807
  throw error;
3682
3808
  }
3683
- console.error({ pipelineString, parameters, parameterNames, error });
3809
+ console.error({ pipelineString, parameters, parameterNames: parameterNamesOrdered, error });
3684
3810
  throw new UnexpectedError(spaceTrim$2((block) => `
3685
3811
  Internal error in prompt template literal
3686
3812
 
@@ -3695,9 +3821,7 @@ function prompt(strings, ...values) {
3695
3821
  continue;
3696
3822
  }
3697
3823
  if (!entry.isInline) {
3698
- pipelineString = pipelineString
3699
- .split(entry.parameterMarker)
3700
- .join(formatParameterPlaceholder(entry.name));
3824
+ pipelineString = pipelineString.split(entry.parameterMarker).join(formatParameterPlaceholder(entry.name));
3701
3825
  }
3702
3826
  }
3703
3827
  const structuredParameters = parameterEntries.filter((entry) => !entry.isPrompt && !entry.isInline);
@@ -5219,60 +5343,12 @@ function getLinguisticHashLanguageConfig(language) {
5219
5343
  return LANGUAGE_CONFIGS[normalized];
5220
5344
  }
5221
5345
 
5222
- // <- TODO: !!!! Remove re-exports
5223
- /**
5224
- * Creates a human-readable hash as a short, story-like phrase.
5225
- *
5226
- * @param wordCount how many words to include (defaults to {@link DEFAULT_LINGUISTIC_HASH_WORD_COUNT}, clamped to
5227
- * {@link MIN_LINGUISTIC_HASH_WORD_COUNT}..{@link MAX_LINGUISTIC_HASH_WORD_COUNT})
5228
- * @param language optional language code (defaults to {@link DEFAULT_LINGUISTIC_HASH_LANGUAGE})
5229
- *
5230
- * @public exported from `@promptbook/utils`
5231
- */
5232
- async function linguisticHash(input, wordCount, language) {
5233
- const hash = computeHash(input);
5234
- const normalizedWordCount = normalizeLinguisticHashWordCount(wordCount);
5235
- const languageConfig = getLinguisticHashLanguageConfig(language);
5236
- const words = createLinguisticHashWords(hash, normalizedWordCount, languageConfig.wordLists);
5237
- return capitalize(words.join(' '));
5238
- }
5239
5346
  /**
5240
5347
  * @@@
5241
5348
  *
5242
5349
  * @private utility of `linguisticHash`
5243
5350
  */
5244
5351
  const HASH_SEGMENT_LENGTH = 8;
5245
- /**
5246
- * The minimum number of words for a linguistic hash.
5247
- *
5248
- * @private utility of `linguisticHash`
5249
- */
5250
- const MIN_LINGUISTIC_HASH_WORD_COUNT = 1;
5251
- /**
5252
- * The default number of words for a linguistic hash.
5253
- *
5254
- * @private utility of `linguisticHash`
5255
- */
5256
- const DEFAULT_LINGUISTIC_HASH_WORD_COUNT = 7;
5257
- /**
5258
- * Extracts a deterministic numeric seed from a SHA-256 hash.
5259
- *
5260
- * @private utility of `linguisticHash`
5261
- */
5262
- function getHashSeed(hash, segmentIndex) {
5263
- const expandedHash = `${hash}${hash}`;
5264
- const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
5265
- return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
5266
- }
5267
- /**
5268
- * Picks a deterministic item from a list based on the hash seed.
5269
- *
5270
- * @private utility of `linguisticHash`
5271
- */
5272
- function pickFromHash(hash, segmentIndex, list) {
5273
- const seed = getHashSeed(hash, segmentIndex);
5274
- return list[seed % list.length];
5275
- }
5276
5352
  /**
5277
5353
  * Ordered word kinds used to build the linguistic hash output.
5278
5354
  *
@@ -5313,16 +5389,23 @@ const MAX_LINGUISTIC_HASH_WORD_COUNT = WORD_SEQUENCE.length;
5313
5389
  */
5314
5390
  const SINGLE_WORD_INDEX = 1;
5315
5391
  /**
5316
- * Normalizes the word count to a supported integer range.
5392
+ * Extracts a deterministic numeric seed from a SHA-256 hash.
5317
5393
  *
5318
5394
  * @private utility of `linguisticHash`
5319
5395
  */
5320
- function normalizeLinguisticHashWordCount(wordCount) {
5321
- if (typeof wordCount !== 'number' || !Number.isFinite(wordCount)) {
5322
- return DEFAULT_LINGUISTIC_HASH_WORD_COUNT;
5323
- }
5324
- const rounded = Math.round(wordCount);
5325
- return Math.min(MAX_LINGUISTIC_HASH_WORD_COUNT, Math.max(MIN_LINGUISTIC_HASH_WORD_COUNT, rounded));
5396
+ function getHashSeed(hash, segmentIndex) {
5397
+ const expandedHash = `${hash}${hash}`;
5398
+ const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
5399
+ return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
5400
+ }
5401
+ /**
5402
+ * Picks a deterministic item from a list based on the hash seed.
5403
+ *
5404
+ * @private utility of `linguisticHash`
5405
+ */
5406
+ function pickFromHash(hash, segmentIndex, list) {
5407
+ const seed = getHashSeed(hash, segmentIndex);
5408
+ return list[seed % list.length];
5326
5409
  }
5327
5410
  /**
5328
5411
  * Picks a deterministic word from the hash by kind.
@@ -5353,6 +5436,49 @@ function createLinguisticHashWords(hash, wordCount, wordLists) {
5353
5436
  return words.slice(0, wordCount);
5354
5437
  }
5355
5438
 
5439
+ /**
5440
+ * The minimum number of words for a linguistic hash.
5441
+ *
5442
+ * @private utility of `linguisticHash`
5443
+ */
5444
+ const MIN_LINGUISTIC_HASH_WORD_COUNT = 1;
5445
+ /**
5446
+ * The default number of words for a linguistic hash.
5447
+ *
5448
+ * @private utility of `linguisticHash`
5449
+ */
5450
+ const DEFAULT_LINGUISTIC_HASH_WORD_COUNT = 7;
5451
+ /**
5452
+ * Normalizes the word count to a supported integer range.
5453
+ *
5454
+ * @private utility of `linguisticHash`
5455
+ */
5456
+ function normalizeLinguisticHashWordCount(wordCount) {
5457
+ if (typeof wordCount !== 'number' || !Number.isFinite(wordCount)) {
5458
+ return DEFAULT_LINGUISTIC_HASH_WORD_COUNT;
5459
+ }
5460
+ const rounded = Math.round(wordCount);
5461
+ return Math.min(MAX_LINGUISTIC_HASH_WORD_COUNT, Math.max(MIN_LINGUISTIC_HASH_WORD_COUNT, rounded));
5462
+ }
5463
+
5464
+ // <- TODO: !!!! Remove re-exports
5465
+ /**
5466
+ * Creates a human-readable hash as a short, story-like phrase.
5467
+ *
5468
+ * @param wordCount how many words to include (defaults to {@link DEFAULT_LINGUISTIC_HASH_WORD_COUNT}, clamped to
5469
+ * {@link MIN_LINGUISTIC_HASH_WORD_COUNT}..{@link MAX_LINGUISTIC_HASH_WORD_COUNT})
5470
+ * @param language optional language code (defaults to {@link DEFAULT_LINGUISTIC_HASH_LANGUAGE})
5471
+ *
5472
+ * @public exported from `@promptbook/utils`
5473
+ */
5474
+ async function linguisticHash(input, wordCount, language) {
5475
+ const hash = computeHash(input);
5476
+ const normalizedWordCount = normalizeLinguisticHashWordCount(wordCount);
5477
+ const languageConfig = getLinguisticHashLanguageConfig(language);
5478
+ const words = createLinguisticHashWords(hash, normalizedWordCount, languageConfig.wordLists);
5479
+ return capitalize(words.join(' '));
5480
+ }
5481
+
5356
5482
  /**
5357
5483
  * Simple wrapper `new Date().toISOString()`
5358
5484
  *
@@ -15968,14 +16094,27 @@ function humanizeAiTextEmdashed(aiText) {
15968
16094
  * @public exported from `@promptbook/markdown-utils`
15969
16095
  */
15970
16096
  function humanizeAiTextQuotes(aiText) {
15971
- return aiText
15972
- .replace(/[“”„‟«»❝❞〝〞〟"]/g, '"')
15973
- .replace(/[‚‘’‛‹›❛❜'ʼ]/g, "'");
16097
+ return aiText.replace(/[“”„‟«»❝❞〝〞〟"]/g, '"').replace(/[‚‘’‛‹›❛❜'ʼ]/g, "'");
15974
16098
  }
15975
16099
  /**
15976
16100
  * Note: [🏂] This function is not tested by itself but together with other cleanup functions with `humanizeAiText`
15977
16101
  */
15978
16102
 
16103
+ /**
16104
+ * Remove bracketed source citation artifacts like `\u30105:1\u2020source\u3011`.
16105
+ *
16106
+ * Note: [??] This function is idempotent.
16107
+ * Tip: If you want to do the full cleanup, look for `humanizeAiText` exported `@promptbook/markdown-utils`
16108
+ *
16109
+ * @public exported from `@promptbook/markdown-utils`
16110
+ */
16111
+ function humanizeAiTextSources(aiText) {
16112
+ return aiText.replace(/[ \t]*\u3010\s*\d+(?:\s*:\s*\d+)?\s*\u2020source\s*\u3011/g, '');
16113
+ }
16114
+ /**
16115
+ * Note: [??] This function is not tested by itself but together with other cleanup functions with `humanizeAiText`
16116
+ */
16117
+
15979
16118
  /**
15980
16119
  * Change unprintable hard spaces to regular spaces and drop zero-width spaces
15981
16120
  *
@@ -15985,9 +16124,7 @@ function humanizeAiTextQuotes(aiText) {
15985
16124
  * @public exported from `@promptbook/markdown-utils`
15986
16125
  */
15987
16126
  function humanizeAiTextWhitespace(aiText) {
15988
- return aiText
15989
- .replace(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, ' ')
15990
- .replace(/[\u200B\uFEFF\u2060]/g, '');
16127
+ return aiText.replace(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, ' ').replace(/[\u200B\uFEFF\u2060]/g, '');
15991
16128
  }
15992
16129
  /**
15993
16130
  * Note: [🏂] This function is not tested by itself but together with other cleanup functions with `humanizeAiText`
@@ -16006,6 +16143,7 @@ function humanizeAiText(aiText) {
16006
16143
  cleanedText = humanizeAiTextEllipsis(cleanedText);
16007
16144
  cleanedText = humanizeAiTextEmdashed(cleanedText);
16008
16145
  cleanedText = humanizeAiTextQuotes(cleanedText);
16146
+ cleanedText = humanizeAiTextSources(cleanedText);
16009
16147
  cleanedText = humanizeAiTextWhitespace(cleanedText);
16010
16148
  return cleanedText;
16011
16149
  }
@@ -18496,17 +18634,32 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18496
18634
  });
18497
18635
  }
18498
18636
  async createNewAssistant(options) {
18637
+ var _a, _b, _c;
18499
18638
  if (!this.isCreatingNewAssistantsAllowed) {
18500
18639
  throw new NotAllowed(`Creating new assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
18501
18640
  }
18502
18641
  // await this.playground();
18503
18642
  const { name, instructions, knowledgeSources, tools } = options;
18643
+ const preparationStartedAtMs = Date.now();
18644
+ const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;
18645
+ const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;
18646
+ if (this.options.isVerbose) {
18647
+ console.info('[🤰]', 'Starting OpenAI assistant creation', {
18648
+ name,
18649
+ knowledgeSourcesCount,
18650
+ toolsCount,
18651
+ instructionsLength: instructions.length,
18652
+ });
18653
+ }
18504
18654
  const client = await this.getClient();
18505
18655
  let vectorStoreId;
18506
18656
  // If knowledge sources are provided, create a vector store with them
18507
18657
  if (knowledgeSources && knowledgeSources.length > 0) {
18508
18658
  if (this.options.isVerbose) {
18509
- console.info(`📚 Creating vector store with ${knowledgeSources.length} knowledge sources...`);
18659
+ console.info('[🤰]', 'Creating vector store with knowledge sources', {
18660
+ name,
18661
+ knowledgeSourcesCount,
18662
+ });
18510
18663
  }
18511
18664
  // Create a vector store
18512
18665
  const vectorStore = await client.beta.vectorStores.create({
@@ -18514,12 +18667,22 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18514
18667
  });
18515
18668
  vectorStoreId = vectorStore.id;
18516
18669
  if (this.options.isVerbose) {
18517
- console.info(`✅ Vector store created: ${vectorStoreId}`);
18670
+ console.info('[🤰]', 'Vector store created', {
18671
+ vectorStoreId,
18672
+ });
18518
18673
  }
18519
18674
  // Upload files from knowledge sources to the vector store
18520
18675
  const fileStreams = [];
18521
- for (const source of knowledgeSources) {
18676
+ for (const [index, source] of knowledgeSources.entries()) {
18522
18677
  try {
18678
+ if (this.options.isVerbose) {
18679
+ console.info('[🤰]', 'Processing knowledge source', {
18680
+ index: index + 1,
18681
+ total: knowledgeSources.length,
18682
+ source,
18683
+ sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
18684
+ });
18685
+ }
18523
18686
  // Check if it's a URL
18524
18687
  if (source.startsWith('http://') || source.startsWith('https://')) {
18525
18688
  // Download the file
@@ -18564,7 +18727,10 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18564
18727
  files: fileStreams,
18565
18728
  });
18566
18729
  if (this.options.isVerbose) {
18567
- console.info(`✅ Uploaded ${fileStreams.length} files to vector store`);
18730
+ console.info('[🤰]', 'Uploaded files to vector store', {
18731
+ vectorStoreId,
18732
+ fileCount: fileStreams.length,
18733
+ });
18568
18734
  }
18569
18735
  }
18570
18736
  catch (error) {
@@ -18592,8 +18758,21 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18592
18758
  },
18593
18759
  };
18594
18760
  }
18761
+ if (this.options.isVerbose) {
18762
+ console.info('[🤰]', 'Creating OpenAI assistant', {
18763
+ name,
18764
+ model: assistantConfig.model,
18765
+ toolCount: (_c = assistantConfig === null || assistantConfig === void 0 ? void 0 : assistantConfig.tools) === null || _c === void 0 ? void 0 : _c.length,
18766
+ hasVectorStore: Boolean(vectorStoreId),
18767
+ });
18768
+ }
18595
18769
  const assistant = await client.beta.assistants.create(assistantConfig);
18596
- console.log(`✅ Assistant created: ${assistant.id}`);
18770
+ if (this.options.isVerbose) {
18771
+ console.info('[🤰]', 'OpenAI assistant created', {
18772
+ assistantId: assistant.id,
18773
+ elapsedMs: Date.now() - preparationStartedAtMs,
18774
+ });
18775
+ }
18597
18776
  // TODO: [🐱‍🚀] Try listing existing assistants
18598
18777
  // TODO: [🐱‍🚀] Try marking existing assistants by DISCRIMINANT
18599
18778
  // TODO: [🐱‍🚀] Allow to update and reconnect to existing assistants
@@ -18604,17 +18783,34 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18604
18783
  });
18605
18784
  }
18606
18785
  async updateAssistant(options) {
18786
+ var _a, _b, _c, _d;
18607
18787
  if (!this.isCreatingNewAssistantsAllowed) {
18608
18788
  throw new NotAllowed(`Updating assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
18609
18789
  }
18610
18790
  const { assistantId, name, instructions, knowledgeSources, tools } = options;
18791
+ const preparationStartedAtMs = Date.now();
18792
+ const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;
18793
+ const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;
18794
+ if (this.options.isVerbose) {
18795
+ console.info('[🤰]', 'Starting OpenAI assistant update', {
18796
+ assistantId,
18797
+ name,
18798
+ knowledgeSourcesCount,
18799
+ toolsCount,
18800
+ instructionsLength: (_c = instructions === null || instructions === void 0 ? void 0 : instructions.length) !== null && _c !== void 0 ? _c : 0,
18801
+ });
18802
+ }
18611
18803
  const client = await this.getClient();
18612
18804
  let vectorStoreId;
18613
18805
  // If knowledge sources are provided, create a vector store with them
18614
18806
  // TODO: [🧠] Reuse vector store creation logic from createNewAssistant
18615
18807
  if (knowledgeSources && knowledgeSources.length > 0) {
18616
18808
  if (this.options.isVerbose) {
18617
- console.info(`📚 Creating vector store for update with ${knowledgeSources.length} knowledge sources...`);
18809
+ console.info('[🤰]', 'Creating vector store for assistant update', {
18810
+ assistantId,
18811
+ name,
18812
+ knowledgeSourcesCount,
18813
+ });
18618
18814
  }
18619
18815
  // Create a vector store
18620
18816
  const vectorStore = await client.beta.vectorStores.create({
@@ -18622,12 +18818,22 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18622
18818
  });
18623
18819
  vectorStoreId = vectorStore.id;
18624
18820
  if (this.options.isVerbose) {
18625
- console.info(`✅ Vector store created: ${vectorStoreId}`);
18821
+ console.info('[🤰]', 'Vector store created for assistant update', {
18822
+ vectorStoreId,
18823
+ });
18626
18824
  }
18627
18825
  // Upload files from knowledge sources to the vector store
18628
18826
  const fileStreams = [];
18629
- for (const source of knowledgeSources) {
18827
+ for (const [index, source] of knowledgeSources.entries()) {
18630
18828
  try {
18829
+ if (this.options.isVerbose) {
18830
+ console.info('[🤰]', 'Processing knowledge source for update', {
18831
+ index: index + 1,
18832
+ total: knowledgeSources.length,
18833
+ source,
18834
+ sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
18835
+ });
18836
+ }
18631
18837
  // Check if it's a URL
18632
18838
  if (source.startsWith('http://') || source.startsWith('https://')) {
18633
18839
  // Download the file
@@ -18672,7 +18878,10 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18672
18878
  files: fileStreams,
18673
18879
  });
18674
18880
  if (this.options.isVerbose) {
18675
- console.info(`✅ Uploaded ${fileStreams.length} files to vector store`);
18881
+ console.info('[🤰]', 'Uploaded files to vector store for update', {
18882
+ vectorStoreId,
18883
+ fileCount: fileStreams.length,
18884
+ });
18676
18885
  }
18677
18886
  }
18678
18887
  catch (error) {
@@ -18696,9 +18905,20 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
18696
18905
  },
18697
18906
  };
18698
18907
  }
18908
+ if (this.options.isVerbose) {
18909
+ console.info('[🤰]', 'Updating OpenAI assistant', {
18910
+ assistantId,
18911
+ name,
18912
+ toolCount: (_d = assistantUpdate === null || assistantUpdate === void 0 ? void 0 : assistantUpdate.tools) === null || _d === void 0 ? void 0 : _d.length,
18913
+ hasVectorStore: Boolean(vectorStoreId),
18914
+ });
18915
+ }
18699
18916
  const assistant = await client.beta.assistants.update(assistantId, assistantUpdate);
18700
18917
  if (this.options.isVerbose) {
18701
- console.log(`✅ Assistant updated: ${assistant.id}`);
18918
+ console.info('[🤰]', 'OpenAI assistant updated', {
18919
+ assistantId: assistant.id,
18920
+ elapsedMs: Date.now() - preparationStartedAtMs,
18921
+ });
18702
18922
  }
18703
18923
  return new OpenAiAssistantExecutionTools({
18704
18924
  ...this.options,
@@ -18757,7 +18977,7 @@ function emitAssistantPreparationProgress(options) {
18757
18977
  toolCalls: [
18758
18978
  {
18759
18979
  name: ASSISTANT_PREPARATION_TOOL_CALL_NAME,
18760
- arguments: {},
18980
+ arguments: options.phase ? { phase: options.phase } : {},
18761
18981
  createdAt: startedAt,
18762
18982
  },
18763
18983
  ],
@@ -18821,10 +19041,32 @@ class AgentLlmExecutionTools {
18821
19041
  */
18822
19042
  async getModelRequirements() {
18823
19043
  if (this._cachedModelRequirements === null) {
19044
+ const preparationStartedAtMs = Date.now();
19045
+ if (this.options.isVerbose) {
19046
+ console.info('[🤰]', 'Preparing agent model requirements', {
19047
+ agent: this.title,
19048
+ });
19049
+ }
18824
19050
  // Get available models from underlying LLM tools for best model selection
19051
+ const availableModelsStartedAtMs = Date.now();
18825
19052
  const availableModels = await this.options.llmTools.listModels();
19053
+ if (this.options.isVerbose) {
19054
+ console.info('[🤰]', 'Available models resolved for agent', {
19055
+ agent: this.title,
19056
+ modelCount: availableModels.length,
19057
+ elapsedMs: Date.now() - availableModelsStartedAtMs,
19058
+ });
19059
+ }
19060
+ const requirementsStartedAtMs = Date.now();
18826
19061
  this._cachedModelRequirements = await createAgentModelRequirements(this.options.agentSource, undefined, // Let the function pick the best model
18827
19062
  availableModels);
19063
+ if (this.options.isVerbose) {
19064
+ console.info('[🤰]', 'Agent model requirements ready', {
19065
+ agent: this.title,
19066
+ elapsedMs: Date.now() - requirementsStartedAtMs,
19067
+ totalElapsedMs: Date.now() - preparationStartedAtMs,
19068
+ });
19069
+ }
18828
19070
  }
18829
19071
  return this._cachedModelRequirements;
18830
19072
  }
@@ -18978,18 +19220,25 @@ class AgentLlmExecutionTools {
18978
19220
  if (cached) {
18979
19221
  if (cached.requirementsHash === requirementsHash) {
18980
19222
  if (this.options.isVerbose) {
18981
- console.log(`1️⃣ Using cached OpenAI Assistant for agent ${this.title}...`);
19223
+ console.info('[🤰]', 'Using cached OpenAI Assistant', {
19224
+ agent: this.title,
19225
+ assistantId: cached.assistantId,
19226
+ });
18982
19227
  }
18983
19228
  assistant = this.options.llmTools.getAssistant(cached.assistantId);
18984
19229
  }
18985
19230
  else {
18986
19231
  if (this.options.isVerbose) {
18987
- console.log(`1️⃣ Updating OpenAI Assistant for agent ${this.title}...`);
19232
+ console.info('[🤰]', 'Updating OpenAI Assistant', {
19233
+ agent: this.title,
19234
+ assistantId: cached.assistantId,
19235
+ });
18988
19236
  }
18989
19237
  emitAssistantPreparationProgress({
18990
19238
  onProgress,
18991
19239
  prompt,
18992
19240
  modelName: this.modelName,
19241
+ phase: 'Updating assistant',
18993
19242
  });
18994
19243
  assistant = await this.options.llmTools.updateAssistant({
18995
19244
  assistantId: cached.assistantId,
@@ -19006,13 +19255,16 @@ class AgentLlmExecutionTools {
19006
19255
  }
19007
19256
  else {
19008
19257
  if (this.options.isVerbose) {
19009
- console.log(`1️⃣ Creating new OpenAI Assistant for agent ${this.title}...`);
19258
+ console.info('[🤰]', 'Creating new OpenAI Assistant', {
19259
+ agent: this.title,
19260
+ });
19010
19261
  }
19011
19262
  // <- TODO: [🐱‍🚀] Check also `isCreatingNewAssistantsAllowed` and warn about it
19012
19263
  emitAssistantPreparationProgress({
19013
19264
  onProgress,
19014
19265
  prompt,
19015
19266
  modelName: this.modelName,
19267
+ phase: 'Creating assistant',
19016
19268
  });
19017
19269
  assistant = await this.options.llmTools.createNewAssistant({
19018
19270
  name: this.title,
@@ -19086,6 +19338,65 @@ AgentLlmExecutionTools.vectorStoreCache = new Map();
19086
19338
  */
19087
19339
 
19088
19340
  var _Agent_instances, _Agent_selfLearnNonce, _Agent_selfLearnSamples, _Agent_selfLearnTeacher;
19341
+ /**
19342
+ * Creates an empty commitment breakdown for self-learning summaries.
19343
+ */
19344
+ function createEmptySelfLearningCommitmentCounts() {
19345
+ return {
19346
+ total: 0,
19347
+ knowledge: 0,
19348
+ rule: 0,
19349
+ persona: 0,
19350
+ other: 0,
19351
+ };
19352
+ }
19353
+ /**
19354
+ * Normalizes teacher commitments into trimmed, display-ready lines.
19355
+ */
19356
+ function getTeacherCommitmentLines(commitments) {
19357
+ return commitments
19358
+ .split(/\r?\n/)
19359
+ .map((line) => line.trim())
19360
+ .filter((line) => line.length > 0 && line !== '---' && !line.startsWith('```'));
19361
+ }
19362
+ /**
19363
+ * Summarizes teacher commitment lines into user-friendly counts for self-learning.
19364
+ */
19365
+ function summarizeTeacherCommitmentLines(lines) {
19366
+ var _a, _b;
19367
+ const counts = createEmptySelfLearningCommitmentCounts();
19368
+ for (const line of lines) {
19369
+ const keyword = (_b = (_a = line.split(/\s+/)[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : '';
19370
+ if (!/^[A-Z][A-Z_-]*$/.test(keyword)) {
19371
+ continue;
19372
+ }
19373
+ counts.total += 1;
19374
+ if (keyword === 'KNOWLEDGE') {
19375
+ counts.knowledge += 1;
19376
+ }
19377
+ else if (keyword === 'RULE') {
19378
+ counts.rule += 1;
19379
+ }
19380
+ else if (keyword === 'PERSONA') {
19381
+ counts.persona += 1;
19382
+ }
19383
+ else {
19384
+ counts.other += 1;
19385
+ }
19386
+ }
19387
+ return counts;
19388
+ }
19389
+ /**
19390
+ * Builds the teacher summary payload for the self-learning tool call.
19391
+ */
19392
+ function buildTeacherSummary(commitments, used) {
19393
+ const commitmentLines = getTeacherCommitmentLines(commitments);
19394
+ return {
19395
+ used,
19396
+ commitmentTypes: summarizeTeacherCommitmentLines(commitmentLines),
19397
+ commitments: commitmentLines.length > 0 ? commitmentLines : undefined,
19398
+ };
19399
+ }
19089
19400
  /**
19090
19401
  * Represents one AI Agent
19091
19402
  *
@@ -19260,16 +19571,29 @@ class Agent extends AgentLlmExecutionTools {
19260
19571
  // Note: [2] Do the append of the samples
19261
19572
  await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnSamples).call(this, prompt, result);
19262
19573
  // Note: [3] Asynchronously call the teacher agent and invoke the silver link. When the teacher fails, keep just the samples
19263
- await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnTeacher).call(this, prompt, result).catch((error) => {
19574
+ let teacherSummary = null;
19575
+ try {
19576
+ teacherSummary = await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnTeacher).call(this, prompt, result);
19577
+ }
19578
+ catch (error) {
19264
19579
  // !!!!! if (this.options.isVerbose) {
19265
19580
  console.error(colors.bgCyan('[Self-learning]') + colors.red(' Failed to learn from teacher agent'));
19266
19581
  console.error(error);
19267
19582
  // }
19268
- });
19583
+ teacherSummary = this.teacherAgent ? buildTeacherSummary('', true) : null;
19584
+ }
19269
19585
  // Note: [4] Notify end of self-learning
19586
+ const completedAt = new Date().toISOString();
19587
+ const selfLearningResult = {
19588
+ success: true,
19589
+ startedAt: selfLearningToolCall.createdAt,
19590
+ completedAt,
19591
+ samplesAdded: 1,
19592
+ teacher: teacherSummary || undefined,
19593
+ };
19270
19594
  const completedSelfLearningToolCall = {
19271
19595
  ...selfLearningToolCall,
19272
- result: { success: true },
19596
+ result: selfLearningResult,
19273
19597
  };
19274
19598
  const finalResult = {
19275
19599
  ...result,
@@ -19318,7 +19642,7 @@ async function _Agent_selfLearnNonce() {
19318
19642
  async function _Agent_selfLearnTeacher(prompt, result) {
19319
19643
  // [1] Call the teacher agent // <- !!!!! Emojis
19320
19644
  if (this.teacherAgent === null) {
19321
- return;
19645
+ return null;
19322
19646
  }
19323
19647
  console.info(colors.bgCyan('[Self-learning]') + colors.cyan(' Teacher'));
19324
19648
  const teacherResult = await this.teacherAgent.callChatModel({
@@ -19373,7 +19697,7 @@ async function _Agent_selfLearnTeacher(prompt, result) {
19373
19697
  if (teacherCommitments === '') {
19374
19698
  console.info(colors.bgCyan('[Self-learning]') +
19375
19699
  colors.cyan(' Teacher agent did not provide new commitments to learn'));
19376
- return;
19700
+ return buildTeacherSummary('', true);
19377
19701
  }
19378
19702
  // [2] Append to the current source
19379
19703
  const currentSource = this.agentSource.value;
@@ -19381,6 +19705,7 @@ async function _Agent_selfLearnTeacher(prompt, result) {
19381
19705
  // <- TODO: [🈲] Use some object-based way how to append on book (with sections `---`)
19382
19706
  // [3] Update the source
19383
19707
  this.agentSource.next(newSource);
19708
+ return buildTeacherSummary(teacherCommitments, true);
19384
19709
  };
19385
19710
  /**
19386
19711
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?