@promptbook/remote-server 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
@@ -39,7 +39,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
39
39
  * @generated
40
40
  * @see https://github.com/webgptorg/promptbook
41
41
  */
42
- const PROMPTBOOK_ENGINE_VERSION = '0.107.0-0';
42
+ const PROMPTBOOK_ENGINE_VERSION = '0.110.0-0';
43
43
  /**
44
44
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
45
45
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -8192,13 +8192,125 @@ function escapePromptParameterValue(value, options) {
8192
8192
  return value.replace(pattern, '\\$&');
8193
8193
  }
8194
8194
  /**
8195
- * Builds the parameter name used in prompt placeholders.
8195
+ * Builds numeric parameter name used in prompt placeholders.
8196
8196
  *
8197
8197
  * @param index Zero-based parameter index.
8198
8198
  */
8199
- function buildParameterName(index) {
8199
+ function buildNumericParameterName(index) {
8200
8200
  return `${index + 1}`;
8201
8201
  }
8202
+ /**
8203
+ * Builds alphabetic parameter name used in prompt placeholders.
8204
+ *
8205
+ * @param index Zero-based parameter index.
8206
+ */
8207
+ function buildAlphabeticParameterName(index) {
8208
+ const alphabet = 'abcdefghijklmnopqrstuvwxyz';
8209
+ let result = '';
8210
+ let remaining = index;
8211
+ while (remaining >= 0) {
8212
+ result = alphabet[remaining % alphabet.length] + result;
8213
+ remaining = Math.floor(remaining / alphabet.length) - 1;
8214
+ }
8215
+ return result;
8216
+ }
8217
+ /**
8218
+ * Converts a positive integer into a Roman numeral string.
8219
+ *
8220
+ * @param value Positive integer value.
8221
+ */
8222
+ function toRomanNumeral(value) {
8223
+ const romanTable = [
8224
+ { symbol: 'M', value: 1000 },
8225
+ { symbol: 'CM', value: 900 },
8226
+ { symbol: 'D', value: 500 },
8227
+ { symbol: 'CD', value: 400 },
8228
+ { symbol: 'C', value: 100 },
8229
+ { symbol: 'XC', value: 90 },
8230
+ { symbol: 'L', value: 50 },
8231
+ { symbol: 'XL', value: 40 },
8232
+ { symbol: 'X', value: 10 },
8233
+ { symbol: 'IX', value: 9 },
8234
+ { symbol: 'V', value: 5 },
8235
+ { symbol: 'IV', value: 4 },
8236
+ { symbol: 'I', value: 1 },
8237
+ ];
8238
+ let remaining = Math.max(1, Math.floor(value));
8239
+ let result = '';
8240
+ for (const entry of romanTable) {
8241
+ while (remaining >= entry.value) {
8242
+ result += entry.symbol;
8243
+ remaining -= entry.value;
8244
+ }
8245
+ }
8246
+ return result;
8247
+ }
8248
+ /**
8249
+ * Builds Roman numeral parameter name used in prompt placeholders.
8250
+ *
8251
+ * @param index Zero-based parameter index.
8252
+ */
8253
+ function buildRomanParameterName(index) {
8254
+ return toRomanNumeral(index + 1);
8255
+ }
8256
+ /**
8257
+ * Creates a parameter name builder that prefixes another builder.
8258
+ *
8259
+ * @param prefix Prefix to add.
8260
+ * @param builder Base builder to wrap.
8261
+ */
8262
+ function buildPrefixedParameterName(prefix, builder) {
8263
+ return (index) => `${prefix}${builder(index)}`;
8264
+ }
8265
+ /**
8266
+ * Ordered list of strategies for parameter naming.
8267
+ */
8268
+ const PARAMETER_NAME_STRATEGIES = [
8269
+ { buildName: buildNumericParameterName },
8270
+ { buildName: buildAlphabeticParameterName },
8271
+ { buildName: buildRomanParameterName },
8272
+ { buildName: buildPrefixedParameterName('p', buildNumericParameterName) },
8273
+ { buildName: buildPrefixedParameterName('p', buildAlphabeticParameterName) },
8274
+ ];
8275
+ /**
8276
+ * Collects bracketed tokens from parameter values to avoid placeholder collisions.
8277
+ *
8278
+ * @param values Parameter values to scan.
8279
+ */
8280
+ function collectBracketedParameterTokens(values) {
8281
+ const tokens = new Set();
8282
+ for (const value of values) {
8283
+ const pattern = /{(\w+)}/g;
8284
+ let match;
8285
+ while ((match = pattern.exec(value)) !== null) {
8286
+ const token = match[1];
8287
+ if (token) {
8288
+ tokens.add(token);
8289
+ }
8290
+ }
8291
+ }
8292
+ return tokens;
8293
+ }
8294
+ /**
8295
+ * Builds parameter names used in prompt placeholders while avoiding collisions.
8296
+ *
8297
+ * @param values Parameter values to scan for conflicting tokens.
8298
+ */
8299
+ function buildParameterNames(values) {
8300
+ const count = values.length;
8301
+ if (count === 0) {
8302
+ return [];
8303
+ }
8304
+ const conflicts = collectBracketedParameterTokens(values);
8305
+ for (const strategy of PARAMETER_NAME_STRATEGIES) {
8306
+ const names = Array.from({ length: count }, (_, index) => strategy.buildName(index));
8307
+ const hasConflict = names.some((name) => conflicts.has(name));
8308
+ if (!hasConflict) {
8309
+ return names;
8310
+ }
8311
+ }
8312
+ return Array.from({ length: count }, (_, index) => `${REPLACING_NONCE}${index + 1}`);
8313
+ }
8202
8314
  /**
8203
8315
  * Formats the placeholder used in the prompt body for a parameter.
8204
8316
  *
@@ -8253,26 +8365,40 @@ function prompt(strings, ...values) {
8253
8365
  return new PromptString(spaceTrim$2(strings.join('')));
8254
8366
  }
8255
8367
  const stringsWithHiddenParameters = strings.map((stringsItem) => hideBrackets(stringsItem));
8256
- const parameterEntries = values.map((value, index) => {
8257
- const name = buildParameterName(index);
8368
+ const parameterMetadata = values.map((value) => {
8258
8369
  const isPrompt = isPromptString(value);
8259
8370
  const stringValue = isPrompt ? value.toString() : valueToString(value);
8260
8371
  const isInline = isPrompt ? true : shouldInlineParameterValue(stringValue);
8261
8372
  const jsonValue = !isPrompt && !isInline ? normalizeJsonString(stringValue) : null;
8373
+ return { isPrompt, stringValue, isInline, jsonValue };
8374
+ });
8375
+ const parameterNames = buildParameterNames(parameterMetadata.map((entry) => entry.stringValue));
8376
+ const parameterEntries = parameterMetadata.map((entry, index) => {
8377
+ var _a;
8378
+ const name = (_a = parameterNames[index]) !== null && _a !== void 0 ? _a : buildNumericParameterName(index);
8262
8379
  const promptMarker = `${REPLACING_NONCE}prompt-${index}`;
8263
8380
  const parameterMarker = `${REPLACING_NONCE}parameter-${index}`;
8264
- const templateValue = isPrompt
8381
+ const templateValue = entry.isPrompt
8265
8382
  ? promptMarker
8266
- : isInline
8267
- ? escapePromptParameterValue(stringValue, { includeBraces: false })
8383
+ : entry.isInline
8384
+ ? escapePromptParameterValue(entry.stringValue, { includeBraces: false })
8268
8385
  : parameterMarker;
8269
- return { name, stringValue, jsonValue, isPrompt, isInline, promptMarker, parameterMarker, templateValue };
8386
+ return {
8387
+ name,
8388
+ stringValue: entry.stringValue,
8389
+ jsonValue: entry.jsonValue,
8390
+ isPrompt: entry.isPrompt,
8391
+ isInline: entry.isInline,
8392
+ promptMarker,
8393
+ parameterMarker,
8394
+ templateValue,
8395
+ };
8270
8396
  });
8271
8397
  const parameters = Object.fromEntries(parameterEntries.map((entry) => [entry.name, entry.templateValue]));
8272
- const parameterNames = parameterEntries.map((entry) => entry.name);
8398
+ const parameterNamesOrdered = parameterEntries.map((entry) => entry.name);
8273
8399
  // Combine strings and values
8274
8400
  let pipelineString = stringsWithHiddenParameters.reduce((result, stringsItem, i) => {
8275
- const parameterName = parameterNames[i];
8401
+ const parameterName = parameterNamesOrdered[i];
8276
8402
  return parameterName === undefined
8277
8403
  ? `${result}${stringsItem}`
8278
8404
  : `${result}${stringsItem}${formatParameterPlaceholder(parameterName)}`;
@@ -8285,7 +8411,7 @@ function prompt(strings, ...values) {
8285
8411
  if (!(error instanceof PipelineExecutionError)) {
8286
8412
  throw error;
8287
8413
  }
8288
- console.error({ pipelineString, parameters, parameterNames, error });
8414
+ console.error({ pipelineString, parameters, parameterNames: parameterNamesOrdered, error });
8289
8415
  throw new UnexpectedError(spaceTrim$2((block) => `
8290
8416
  Internal error in prompt template literal
8291
8417
 
@@ -8300,9 +8426,7 @@ function prompt(strings, ...values) {
8300
8426
  continue;
8301
8427
  }
8302
8428
  if (!entry.isInline) {
8303
- pipelineString = pipelineString
8304
- .split(entry.parameterMarker)
8305
- .join(formatParameterPlaceholder(entry.name));
8429
+ pipelineString = pipelineString.split(entry.parameterMarker).join(formatParameterPlaceholder(entry.name));
8306
8430
  }
8307
8431
  }
8308
8432
  const structuredParameters = parameterEntries.filter((entry) => !entry.isPrompt && !entry.isInline);
@@ -9630,60 +9754,12 @@ function getLinguisticHashLanguageConfig(language) {
9630
9754
  return LANGUAGE_CONFIGS[normalized];
9631
9755
  }
9632
9756
 
9633
- // <- TODO: !!!! Remove re-exports
9634
- /**
9635
- * Creates a human-readable hash as a short, story-like phrase.
9636
- *
9637
- * @param wordCount how many words to include (defaults to {@link DEFAULT_LINGUISTIC_HASH_WORD_COUNT}, clamped to
9638
- * {@link MIN_LINGUISTIC_HASH_WORD_COUNT}..{@link MAX_LINGUISTIC_HASH_WORD_COUNT})
9639
- * @param language optional language code (defaults to {@link DEFAULT_LINGUISTIC_HASH_LANGUAGE})
9640
- *
9641
- * @public exported from `@promptbook/utils`
9642
- */
9643
- async function linguisticHash(input, wordCount, language) {
9644
- const hash = computeHash(input);
9645
- const normalizedWordCount = normalizeLinguisticHashWordCount(wordCount);
9646
- const languageConfig = getLinguisticHashLanguageConfig(language);
9647
- const words = createLinguisticHashWords(hash, normalizedWordCount, languageConfig.wordLists);
9648
- return capitalize(words.join(' '));
9649
- }
9650
9757
  /**
9651
9758
  * @@@
9652
9759
  *
9653
9760
  * @private utility of `linguisticHash`
9654
9761
  */
9655
9762
  const HASH_SEGMENT_LENGTH = 8;
9656
- /**
9657
- * The minimum number of words for a linguistic hash.
9658
- *
9659
- * @private utility of `linguisticHash`
9660
- */
9661
- const MIN_LINGUISTIC_HASH_WORD_COUNT = 1;
9662
- /**
9663
- * The default number of words for a linguistic hash.
9664
- *
9665
- * @private utility of `linguisticHash`
9666
- */
9667
- const DEFAULT_LINGUISTIC_HASH_WORD_COUNT = 7;
9668
- /**
9669
- * Extracts a deterministic numeric seed from a SHA-256 hash.
9670
- *
9671
- * @private utility of `linguisticHash`
9672
- */
9673
- function getHashSeed(hash, segmentIndex) {
9674
- const expandedHash = `${hash}${hash}`;
9675
- const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
9676
- return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
9677
- }
9678
- /**
9679
- * Picks a deterministic item from a list based on the hash seed.
9680
- *
9681
- * @private utility of `linguisticHash`
9682
- */
9683
- function pickFromHash(hash, segmentIndex, list) {
9684
- const seed = getHashSeed(hash, segmentIndex);
9685
- return list[seed % list.length];
9686
- }
9687
9763
  /**
9688
9764
  * Ordered word kinds used to build the linguistic hash output.
9689
9765
  *
@@ -9724,16 +9800,23 @@ const MAX_LINGUISTIC_HASH_WORD_COUNT = WORD_SEQUENCE.length;
9724
9800
  */
9725
9801
  const SINGLE_WORD_INDEX = 1;
9726
9802
  /**
9727
- * Normalizes the word count to a supported integer range.
9803
+ * Extracts a deterministic numeric seed from a SHA-256 hash.
9728
9804
  *
9729
9805
  * @private utility of `linguisticHash`
9730
9806
  */
9731
- function normalizeLinguisticHashWordCount(wordCount) {
9732
- if (typeof wordCount !== 'number' || !Number.isFinite(wordCount)) {
9733
- return DEFAULT_LINGUISTIC_HASH_WORD_COUNT;
9734
- }
9735
- const rounded = Math.round(wordCount);
9736
- return Math.min(MAX_LINGUISTIC_HASH_WORD_COUNT, Math.max(MIN_LINGUISTIC_HASH_WORD_COUNT, rounded));
9807
+ function getHashSeed(hash, segmentIndex) {
9808
+ const expandedHash = `${hash}${hash}`;
9809
+ const start = (segmentIndex * HASH_SEGMENT_LENGTH + segmentIndex) % hash.length;
9810
+ return parseInt(expandedHash.substring(start, start + HASH_SEGMENT_LENGTH), 16);
9811
+ }
9812
+ /**
9813
+ * Picks a deterministic item from a list based on the hash seed.
9814
+ *
9815
+ * @private utility of `linguisticHash`
9816
+ */
9817
+ function pickFromHash(hash, segmentIndex, list) {
9818
+ const seed = getHashSeed(hash, segmentIndex);
9819
+ return list[seed % list.length];
9737
9820
  }
9738
9821
  /**
9739
9822
  * Picks a deterministic word from the hash by kind.
@@ -9764,6 +9847,49 @@ function createLinguisticHashWords(hash, wordCount, wordLists) {
9764
9847
  return words.slice(0, wordCount);
9765
9848
  }
9766
9849
 
9850
+ /**
9851
+ * The minimum number of words for a linguistic hash.
9852
+ *
9853
+ * @private utility of `linguisticHash`
9854
+ */
9855
+ const MIN_LINGUISTIC_HASH_WORD_COUNT = 1;
9856
+ /**
9857
+ * The default number of words for a linguistic hash.
9858
+ *
9859
+ * @private utility of `linguisticHash`
9860
+ */
9861
+ const DEFAULT_LINGUISTIC_HASH_WORD_COUNT = 7;
9862
+ /**
9863
+ * Normalizes the word count to a supported integer range.
9864
+ *
9865
+ * @private utility of `linguisticHash`
9866
+ */
9867
+ function normalizeLinguisticHashWordCount(wordCount) {
9868
+ if (typeof wordCount !== 'number' || !Number.isFinite(wordCount)) {
9869
+ return DEFAULT_LINGUISTIC_HASH_WORD_COUNT;
9870
+ }
9871
+ const rounded = Math.round(wordCount);
9872
+ return Math.min(MAX_LINGUISTIC_HASH_WORD_COUNT, Math.max(MIN_LINGUISTIC_HASH_WORD_COUNT, rounded));
9873
+ }
9874
+
9875
+ // <- TODO: !!!! Remove re-exports
9876
+ /**
9877
+ * Creates a human-readable hash as a short, story-like phrase.
9878
+ *
9879
+ * @param wordCount how many words to include (defaults to {@link DEFAULT_LINGUISTIC_HASH_WORD_COUNT}, clamped to
9880
+ * {@link MIN_LINGUISTIC_HASH_WORD_COUNT}..{@link MAX_LINGUISTIC_HASH_WORD_COUNT})
9881
+ * @param language optional language code (defaults to {@link DEFAULT_LINGUISTIC_HASH_LANGUAGE})
9882
+ *
9883
+ * @public exported from `@promptbook/utils`
9884
+ */
9885
+ async function linguisticHash(input, wordCount, language) {
9886
+ const hash = computeHash(input);
9887
+ const normalizedWordCount = normalizeLinguisticHashWordCount(wordCount);
9888
+ const languageConfig = getLinguisticHashLanguageConfig(language);
9889
+ const words = createLinguisticHashWords(hash, normalizedWordCount, languageConfig.wordLists);
9890
+ return capitalize(words.join(' '));
9891
+ }
9892
+
9767
9893
  /**
9768
9894
  * Simple wrapper `new Date().toISOString()`
9769
9895
  *
@@ -18406,14 +18532,27 @@ function humanizeAiTextEmdashed(aiText) {
18406
18532
  * @public exported from `@promptbook/markdown-utils`
18407
18533
  */
18408
18534
  function humanizeAiTextQuotes(aiText) {
18409
- return aiText
18410
- .replace(/[“”„‟«»❝❞〝〞〟"]/g, '"')
18411
- .replace(/[‚‘’‛‹›❛❜'ʼ]/g, "'");
18535
+ return aiText.replace(/[“”„‟«»❝❞〝〞〟"]/g, '"').replace(/[‚‘’‛‹›❛❜'ʼ]/g, "'");
18412
18536
  }
18413
18537
  /**
18414
18538
  * Note: [🏂] This function is not tested by itself but together with other cleanup functions with `humanizeAiText`
18415
18539
  */
18416
18540
 
18541
+ /**
18542
+ * Remove bracketed source citation artifacts like `\u30105:1\u2020source\u3011`.
18543
+ *
18544
+ * Note: [??] This function is idempotent.
18545
+ * Tip: If you want to do the full cleanup, look for `humanizeAiText` exported `@promptbook/markdown-utils`
18546
+ *
18547
+ * @public exported from `@promptbook/markdown-utils`
18548
+ */
18549
+ function humanizeAiTextSources(aiText) {
18550
+ return aiText.replace(/[ \t]*\u3010\s*\d+(?:\s*:\s*\d+)?\s*\u2020source\s*\u3011/g, '');
18551
+ }
18552
+ /**
18553
+ * Note: [??] This function is not tested by itself but together with other cleanup functions with `humanizeAiText`
18554
+ */
18555
+
18417
18556
  /**
18418
18557
  * Change unprintable hard spaces to regular spaces and drop zero-width spaces
18419
18558
  *
@@ -18423,9 +18562,7 @@ function humanizeAiTextQuotes(aiText) {
18423
18562
  * @public exported from `@promptbook/markdown-utils`
18424
18563
  */
18425
18564
  function humanizeAiTextWhitespace(aiText) {
18426
- return aiText
18427
- .replace(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, ' ')
18428
- .replace(/[\u200B\uFEFF\u2060]/g, '');
18565
+ return aiText.replace(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, ' ').replace(/[\u200B\uFEFF\u2060]/g, '');
18429
18566
  }
18430
18567
  /**
18431
18568
  * Note: [🏂] This function is not tested by itself but together with other cleanup functions with `humanizeAiText`
@@ -18444,6 +18581,7 @@ function humanizeAiText(aiText) {
18444
18581
  cleanedText = humanizeAiTextEllipsis(cleanedText);
18445
18582
  cleanedText = humanizeAiTextEmdashed(cleanedText);
18446
18583
  cleanedText = humanizeAiTextQuotes(cleanedText);
18584
+ cleanedText = humanizeAiTextSources(cleanedText);
18447
18585
  cleanedText = humanizeAiTextWhitespace(cleanedText);
18448
18586
  return cleanedText;
18449
18587
  }
@@ -20934,17 +21072,32 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20934
21072
  });
20935
21073
  }
20936
21074
  async createNewAssistant(options) {
21075
+ var _a, _b, _c;
20937
21076
  if (!this.isCreatingNewAssistantsAllowed) {
20938
21077
  throw new NotAllowed(`Creating new assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
20939
21078
  }
20940
21079
  // await this.playground();
20941
21080
  const { name, instructions, knowledgeSources, tools } = options;
21081
+ const preparationStartedAtMs = Date.now();
21082
+ const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;
21083
+ const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;
21084
+ if (this.options.isVerbose) {
21085
+ console.info('[🤰]', 'Starting OpenAI assistant creation', {
21086
+ name,
21087
+ knowledgeSourcesCount,
21088
+ toolsCount,
21089
+ instructionsLength: instructions.length,
21090
+ });
21091
+ }
20942
21092
  const client = await this.getClient();
20943
21093
  let vectorStoreId;
20944
21094
  // If knowledge sources are provided, create a vector store with them
20945
21095
  if (knowledgeSources && knowledgeSources.length > 0) {
20946
21096
  if (this.options.isVerbose) {
20947
- console.info(`📚 Creating vector store with ${knowledgeSources.length} knowledge sources...`);
21097
+ console.info('[🤰]', 'Creating vector store with knowledge sources', {
21098
+ name,
21099
+ knowledgeSourcesCount,
21100
+ });
20948
21101
  }
20949
21102
  // Create a vector store
20950
21103
  const vectorStore = await client.beta.vectorStores.create({
@@ -20952,12 +21105,22 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
20952
21105
  });
20953
21106
  vectorStoreId = vectorStore.id;
20954
21107
  if (this.options.isVerbose) {
20955
- console.info(`✅ Vector store created: ${vectorStoreId}`);
21108
+ console.info('[🤰]', 'Vector store created', {
21109
+ vectorStoreId,
21110
+ });
20956
21111
  }
20957
21112
  // Upload files from knowledge sources to the vector store
20958
21113
  const fileStreams = [];
20959
- for (const source of knowledgeSources) {
21114
+ for (const [index, source] of knowledgeSources.entries()) {
20960
21115
  try {
21116
+ if (this.options.isVerbose) {
21117
+ console.info('[🤰]', 'Processing knowledge source', {
21118
+ index: index + 1,
21119
+ total: knowledgeSources.length,
21120
+ source,
21121
+ sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
21122
+ });
21123
+ }
20961
21124
  // Check if it's a URL
20962
21125
  if (source.startsWith('http://') || source.startsWith('https://')) {
20963
21126
  // Download the file
@@ -21002,7 +21165,10 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
21002
21165
  files: fileStreams,
21003
21166
  });
21004
21167
  if (this.options.isVerbose) {
21005
- console.info(`✅ Uploaded ${fileStreams.length} files to vector store`);
21168
+ console.info('[🤰]', 'Uploaded files to vector store', {
21169
+ vectorStoreId,
21170
+ fileCount: fileStreams.length,
21171
+ });
21006
21172
  }
21007
21173
  }
21008
21174
  catch (error) {
@@ -21030,8 +21196,21 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
21030
21196
  },
21031
21197
  };
21032
21198
  }
21199
+ if (this.options.isVerbose) {
21200
+ console.info('[🤰]', 'Creating OpenAI assistant', {
21201
+ name,
21202
+ model: assistantConfig.model,
21203
+ toolCount: (_c = assistantConfig === null || assistantConfig === void 0 ? void 0 : assistantConfig.tools) === null || _c === void 0 ? void 0 : _c.length,
21204
+ hasVectorStore: Boolean(vectorStoreId),
21205
+ });
21206
+ }
21033
21207
  const assistant = await client.beta.assistants.create(assistantConfig);
21034
- console.log(`✅ Assistant created: ${assistant.id}`);
21208
+ if (this.options.isVerbose) {
21209
+ console.info('[🤰]', 'OpenAI assistant created', {
21210
+ assistantId: assistant.id,
21211
+ elapsedMs: Date.now() - preparationStartedAtMs,
21212
+ });
21213
+ }
21035
21214
  // TODO: [🐱‍🚀] Try listing existing assistants
21036
21215
  // TODO: [🐱‍🚀] Try marking existing assistants by DISCRIMINANT
21037
21216
  // TODO: [🐱‍🚀] Allow to update and reconnect to existing assistants
@@ -21042,17 +21221,34 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
21042
21221
  });
21043
21222
  }
21044
21223
  async updateAssistant(options) {
21224
+ var _a, _b, _c, _d;
21045
21225
  if (!this.isCreatingNewAssistantsAllowed) {
21046
21226
  throw new NotAllowed(`Updating assistants is not allowed. Set \`isCreatingNewAssistantsAllowed: true\` in options to enable this feature.`);
21047
21227
  }
21048
21228
  const { assistantId, name, instructions, knowledgeSources, tools } = options;
21229
+ const preparationStartedAtMs = Date.now();
21230
+ const knowledgeSourcesCount = (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0;
21231
+ const toolsCount = (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0;
21232
+ if (this.options.isVerbose) {
21233
+ console.info('[🤰]', 'Starting OpenAI assistant update', {
21234
+ assistantId,
21235
+ name,
21236
+ knowledgeSourcesCount,
21237
+ toolsCount,
21238
+ instructionsLength: (_c = instructions === null || instructions === void 0 ? void 0 : instructions.length) !== null && _c !== void 0 ? _c : 0,
21239
+ });
21240
+ }
21049
21241
  const client = await this.getClient();
21050
21242
  let vectorStoreId;
21051
21243
  // If knowledge sources are provided, create a vector store with them
21052
21244
  // TODO: [🧠] Reuse vector store creation logic from createNewAssistant
21053
21245
  if (knowledgeSources && knowledgeSources.length > 0) {
21054
21246
  if (this.options.isVerbose) {
21055
- console.info(`📚 Creating vector store for update with ${knowledgeSources.length} knowledge sources...`);
21247
+ console.info('[🤰]', 'Creating vector store for assistant update', {
21248
+ assistantId,
21249
+ name,
21250
+ knowledgeSourcesCount,
21251
+ });
21056
21252
  }
21057
21253
  // Create a vector store
21058
21254
  const vectorStore = await client.beta.vectorStores.create({
@@ -21060,12 +21256,22 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
21060
21256
  });
21061
21257
  vectorStoreId = vectorStore.id;
21062
21258
  if (this.options.isVerbose) {
21063
- console.info(`✅ Vector store created: ${vectorStoreId}`);
21259
+ console.info('[🤰]', 'Vector store created for assistant update', {
21260
+ vectorStoreId,
21261
+ });
21064
21262
  }
21065
21263
  // Upload files from knowledge sources to the vector store
21066
21264
  const fileStreams = [];
21067
- for (const source of knowledgeSources) {
21265
+ for (const [index, source] of knowledgeSources.entries()) {
21068
21266
  try {
21267
+ if (this.options.isVerbose) {
21268
+ console.info('[🤰]', 'Processing knowledge source for update', {
21269
+ index: index + 1,
21270
+ total: knowledgeSources.length,
21271
+ source,
21272
+ sourceType: source.startsWith('http') || source.startsWith('https') ? 'url' : 'file',
21273
+ });
21274
+ }
21069
21275
  // Check if it's a URL
21070
21276
  if (source.startsWith('http://') || source.startsWith('https://')) {
21071
21277
  // Download the file
@@ -21110,7 +21316,10 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
21110
21316
  files: fileStreams,
21111
21317
  });
21112
21318
  if (this.options.isVerbose) {
21113
- console.info(`✅ Uploaded ${fileStreams.length} files to vector store`);
21319
+ console.info('[🤰]', 'Uploaded files to vector store for update', {
21320
+ vectorStoreId,
21321
+ fileCount: fileStreams.length,
21322
+ });
21114
21323
  }
21115
21324
  }
21116
21325
  catch (error) {
@@ -21134,9 +21343,20 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
21134
21343
  },
21135
21344
  };
21136
21345
  }
21346
+ if (this.options.isVerbose) {
21347
+ console.info('[🤰]', 'Updating OpenAI assistant', {
21348
+ assistantId,
21349
+ name,
21350
+ toolCount: (_d = assistantUpdate === null || assistantUpdate === void 0 ? void 0 : assistantUpdate.tools) === null || _d === void 0 ? void 0 : _d.length,
21351
+ hasVectorStore: Boolean(vectorStoreId),
21352
+ });
21353
+ }
21137
21354
  const assistant = await client.beta.assistants.update(assistantId, assistantUpdate);
21138
21355
  if (this.options.isVerbose) {
21139
- console.log(`✅ Assistant updated: ${assistant.id}`);
21356
+ console.info('[🤰]', 'OpenAI assistant updated', {
21357
+ assistantId: assistant.id,
21358
+ elapsedMs: Date.now() - preparationStartedAtMs,
21359
+ });
21140
21360
  }
21141
21361
  return new OpenAiAssistantExecutionTools({
21142
21362
  ...this.options,
@@ -21195,7 +21415,7 @@ function emitAssistantPreparationProgress(options) {
21195
21415
  toolCalls: [
21196
21416
  {
21197
21417
  name: ASSISTANT_PREPARATION_TOOL_CALL_NAME,
21198
- arguments: {},
21418
+ arguments: options.phase ? { phase: options.phase } : {},
21199
21419
  createdAt: startedAt,
21200
21420
  },
21201
21421
  ],
@@ -21259,10 +21479,32 @@ class AgentLlmExecutionTools {
21259
21479
  */
21260
21480
  async getModelRequirements() {
21261
21481
  if (this._cachedModelRequirements === null) {
21482
+ const preparationStartedAtMs = Date.now();
21483
+ if (this.options.isVerbose) {
21484
+ console.info('[🤰]', 'Preparing agent model requirements', {
21485
+ agent: this.title,
21486
+ });
21487
+ }
21262
21488
  // Get available models from underlying LLM tools for best model selection
21489
+ const availableModelsStartedAtMs = Date.now();
21263
21490
  const availableModels = await this.options.llmTools.listModels();
21491
+ if (this.options.isVerbose) {
21492
+ console.info('[🤰]', 'Available models resolved for agent', {
21493
+ agent: this.title,
21494
+ modelCount: availableModels.length,
21495
+ elapsedMs: Date.now() - availableModelsStartedAtMs,
21496
+ });
21497
+ }
21498
+ const requirementsStartedAtMs = Date.now();
21264
21499
  this._cachedModelRequirements = await createAgentModelRequirements(this.options.agentSource, undefined, // Let the function pick the best model
21265
21500
  availableModels);
21501
+ if (this.options.isVerbose) {
21502
+ console.info('[🤰]', 'Agent model requirements ready', {
21503
+ agent: this.title,
21504
+ elapsedMs: Date.now() - requirementsStartedAtMs,
21505
+ totalElapsedMs: Date.now() - preparationStartedAtMs,
21506
+ });
21507
+ }
21266
21508
  }
21267
21509
  return this._cachedModelRequirements;
21268
21510
  }
@@ -21416,18 +21658,25 @@ class AgentLlmExecutionTools {
21416
21658
  if (cached) {
21417
21659
  if (cached.requirementsHash === requirementsHash) {
21418
21660
  if (this.options.isVerbose) {
21419
- console.log(`1️⃣ Using cached OpenAI Assistant for agent ${this.title}...`);
21661
+ console.info('[🤰]', 'Using cached OpenAI Assistant', {
21662
+ agent: this.title,
21663
+ assistantId: cached.assistantId,
21664
+ });
21420
21665
  }
21421
21666
  assistant = this.options.llmTools.getAssistant(cached.assistantId);
21422
21667
  }
21423
21668
  else {
21424
21669
  if (this.options.isVerbose) {
21425
- console.log(`1️⃣ Updating OpenAI Assistant for agent ${this.title}...`);
21670
+ console.info('[🤰]', 'Updating OpenAI Assistant', {
21671
+ agent: this.title,
21672
+ assistantId: cached.assistantId,
21673
+ });
21426
21674
  }
21427
21675
  emitAssistantPreparationProgress({
21428
21676
  onProgress,
21429
21677
  prompt,
21430
21678
  modelName: this.modelName,
21679
+ phase: 'Updating assistant',
21431
21680
  });
21432
21681
  assistant = await this.options.llmTools.updateAssistant({
21433
21682
  assistantId: cached.assistantId,
@@ -21444,13 +21693,16 @@ class AgentLlmExecutionTools {
21444
21693
  }
21445
21694
  else {
21446
21695
  if (this.options.isVerbose) {
21447
- console.log(`1️⃣ Creating new OpenAI Assistant for agent ${this.title}...`);
21696
+ console.info('[🤰]', 'Creating new OpenAI Assistant', {
21697
+ agent: this.title,
21698
+ });
21448
21699
  }
21449
21700
  // <- TODO: [🐱‍🚀] Check also `isCreatingNewAssistantsAllowed` and warn about it
21450
21701
  emitAssistantPreparationProgress({
21451
21702
  onProgress,
21452
21703
  prompt,
21453
21704
  modelName: this.modelName,
21705
+ phase: 'Creating assistant',
21454
21706
  });
21455
21707
  assistant = await this.options.llmTools.createNewAssistant({
21456
21708
  name: this.title,
@@ -21524,6 +21776,65 @@ AgentLlmExecutionTools.vectorStoreCache = new Map();
21524
21776
  */
21525
21777
 
21526
21778
  var _Agent_instances, _Agent_selfLearnNonce, _Agent_selfLearnSamples, _Agent_selfLearnTeacher;
21779
+ /**
21780
+ * Creates an empty commitment breakdown for self-learning summaries.
21781
+ */
21782
+ function createEmptySelfLearningCommitmentCounts() {
21783
+ return {
21784
+ total: 0,
21785
+ knowledge: 0,
21786
+ rule: 0,
21787
+ persona: 0,
21788
+ other: 0,
21789
+ };
21790
+ }
21791
+ /**
21792
+ * Normalizes teacher commitments into trimmed, display-ready lines.
21793
+ */
21794
+ function getTeacherCommitmentLines(commitments) {
21795
+ return commitments
21796
+ .split(/\r?\n/)
21797
+ .map((line) => line.trim())
21798
+ .filter((line) => line.length > 0 && line !== '---' && !line.startsWith('```'));
21799
+ }
21800
+ /**
21801
+ * Summarizes teacher commitment lines into user-friendly counts for self-learning.
21802
+ */
21803
+ function summarizeTeacherCommitmentLines(lines) {
21804
+ var _a, _b;
21805
+ const counts = createEmptySelfLearningCommitmentCounts();
21806
+ for (const line of lines) {
21807
+ const keyword = (_b = (_a = line.split(/\s+/)[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : '';
21808
+ if (!/^[A-Z][A-Z_-]*$/.test(keyword)) {
21809
+ continue;
21810
+ }
21811
+ counts.total += 1;
21812
+ if (keyword === 'KNOWLEDGE') {
21813
+ counts.knowledge += 1;
21814
+ }
21815
+ else if (keyword === 'RULE') {
21816
+ counts.rule += 1;
21817
+ }
21818
+ else if (keyword === 'PERSONA') {
21819
+ counts.persona += 1;
21820
+ }
21821
+ else {
21822
+ counts.other += 1;
21823
+ }
21824
+ }
21825
+ return counts;
21826
+ }
21827
+ /**
21828
+ * Builds the teacher summary payload for the self-learning tool call.
21829
+ */
21830
+ function buildTeacherSummary(commitments, used) {
21831
+ const commitmentLines = getTeacherCommitmentLines(commitments);
21832
+ return {
21833
+ used,
21834
+ commitmentTypes: summarizeTeacherCommitmentLines(commitmentLines),
21835
+ commitments: commitmentLines.length > 0 ? commitmentLines : undefined,
21836
+ };
21837
+ }
21527
21838
  /**
21528
21839
  * Represents one AI Agent
21529
21840
  *
@@ -21698,16 +22009,29 @@ class Agent extends AgentLlmExecutionTools {
21698
22009
  // Note: [2] Do the append of the samples
21699
22010
  await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnSamples).call(this, prompt, result);
21700
22011
  // Note: [3] Asynchronously call the teacher agent and invoke the silver link. When the teacher fails, keep just the samples
21701
- await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnTeacher).call(this, prompt, result).catch((error) => {
22012
+ let teacherSummary = null;
22013
+ try {
22014
+ teacherSummary = await __classPrivateFieldGet(this, _Agent_instances, "m", _Agent_selfLearnTeacher).call(this, prompt, result);
22015
+ }
22016
+ catch (error) {
21702
22017
  // !!!!! if (this.options.isVerbose) {
21703
22018
  console.error(colors.bgCyan('[Self-learning]') + colors.red(' Failed to learn from teacher agent'));
21704
22019
  console.error(error);
21705
22020
  // }
21706
- });
22021
+ teacherSummary = this.teacherAgent ? buildTeacherSummary('', true) : null;
22022
+ }
21707
22023
  // Note: [4] Notify end of self-learning
22024
+ const completedAt = new Date().toISOString();
22025
+ const selfLearningResult = {
22026
+ success: true,
22027
+ startedAt: selfLearningToolCall.createdAt,
22028
+ completedAt,
22029
+ samplesAdded: 1,
22030
+ teacher: teacherSummary || undefined,
22031
+ };
21708
22032
  const completedSelfLearningToolCall = {
21709
22033
  ...selfLearningToolCall,
21710
- result: { success: true },
22034
+ result: selfLearningResult,
21711
22035
  };
21712
22036
  const finalResult = {
21713
22037
  ...result,
@@ -21756,7 +22080,7 @@ async function _Agent_selfLearnNonce() {
21756
22080
  async function _Agent_selfLearnTeacher(prompt, result) {
21757
22081
  // [1] Call the teacher agent // <- !!!!! Emojis
21758
22082
  if (this.teacherAgent === null) {
21759
- return;
22083
+ return null;
21760
22084
  }
21761
22085
  console.info(colors.bgCyan('[Self-learning]') + colors.cyan(' Teacher'));
21762
22086
  const teacherResult = await this.teacherAgent.callChatModel({
@@ -21811,7 +22135,7 @@ async function _Agent_selfLearnTeacher(prompt, result) {
21811
22135
  if (teacherCommitments === '') {
21812
22136
  console.info(colors.bgCyan('[Self-learning]') +
21813
22137
  colors.cyan(' Teacher agent did not provide new commitments to learn'));
21814
- return;
22138
+ return buildTeacherSummary('', true);
21815
22139
  }
21816
22140
  // [2] Append to the current source
21817
22141
  const currentSource = this.agentSource.value;
@@ -21819,6 +22143,7 @@ async function _Agent_selfLearnTeacher(prompt, result) {
21819
22143
  // <- TODO: [🈲] Use some object-based way how to append on book (with sections `---`)
21820
22144
  // [3] Update the source
21821
22145
  this.agentSource.next(newSource);
22146
+ return buildTeacherSummary(teacherCommitments, true);
21822
22147
  };
21823
22148
  /**
21824
22149
  * TODO: [🧠][😰]Agent is not working with the parameters, should it be?