@promptbook/core 0.104.0-0 → 0.104.0-10

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 (42) hide show
  1. package/esm/index.es.js +487 -159
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/servers.d.ts +8 -0
  4. package/esm/typings/src/_packages/core.index.d.ts +2 -0
  5. package/esm/typings/src/_packages/types.index.d.ts +10 -2
  6. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +6 -1
  7. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirements.d.ts +6 -6
  8. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.closed.test.d.ts +1 -0
  9. package/esm/typings/src/book-2.0/utils/generatePlaceholderAgentProfileImageUrl.d.ts +3 -3
  10. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
  11. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  12. package/esm/typings/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +13 -0
  13. package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
  14. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +7 -11
  15. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +2 -2
  16. package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
  17. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +21 -11
  18. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +80 -14
  19. package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
  20. package/esm/typings/src/commitments/index.d.ts +2 -1
  21. package/esm/typings/src/llm-providers/_multiple/MultipleLlmExecutionTools.d.ts +6 -2
  22. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +1 -1
  23. package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
  24. package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
  25. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -0
  26. package/esm/typings/src/types/Message.d.ts +49 -0
  27. package/esm/typings/src/types/ModelRequirements.d.ts +38 -14
  28. package/esm/typings/src/types/typeAliases.d.ts +23 -1
  29. package/esm/typings/src/utils/color/utils/colorToDataUrl.d.ts +2 -1
  30. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
  31. package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
  32. package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
  33. package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
  34. package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
  35. package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
  36. package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
  37. package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
  38. package/esm/typings/src/version.d.ts +1 -1
  39. package/package.json +1 -1
  40. package/umd/index.umd.js +493 -164
  41. package/umd/index.umd.js.map +1 -1
  42. package/esm/typings/src/book-2.0/utils/generateGravatarUrl.d.ts +0 -10
package/umd/index.umd.js CHANGED
@@ -28,7 +28,7 @@
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.104.0-0';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.104.0-10';
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
@@ -38,6 +38,8 @@
38
38
  * Core Promptbook server configuration.
39
39
  *
40
40
  * This server is also used for auto-federation in the Agents Server.
41
+ *
42
+ * @public exported from `@promptbook/core`
41
43
  */
42
44
  const CORE_SERVER = {
43
45
  title: 'Promptbook Core',
@@ -3745,6 +3747,15 @@
3745
3747
  return promptResult;
3746
3748
  };
3747
3749
  }
3750
+ if (llmTools.callImageGenerationModel !== undefined) {
3751
+ proxyTools.callImageGenerationModel = async (prompt) => {
3752
+ // console.info('[🚕] callImageGenerationModel through countTotalUsage');
3753
+ const promptResult = await llmTools.callImageGenerationModel(prompt);
3754
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3755
+ spending.next(promptResult.usage);
3756
+ return promptResult;
3757
+ };
3758
+ }
3748
3759
  // <- Note: [🤖]
3749
3760
  return proxyTools;
3750
3761
  }
@@ -3854,6 +3865,12 @@
3854
3865
  callEmbeddingModel(prompt) {
3855
3866
  return this.callCommonModel(prompt);
3856
3867
  }
3868
+ /**
3869
+ * Calls the best available embedding model
3870
+ */
3871
+ callImageGenerationModel(prompt) {
3872
+ return this.callCommonModel(prompt);
3873
+ }
3857
3874
  // <- Note: [🤖]
3858
3875
  /**
3859
3876
  * Calls the best available model
@@ -3880,6 +3897,11 @@
3880
3897
  continue llm;
3881
3898
  }
3882
3899
  return await llmExecutionTools.callEmbeddingModel(prompt);
3900
+ case 'IMAGE_GENERATION':
3901
+ if (llmExecutionTools.callImageGenerationModel === undefined) {
3902
+ continue llm;
3903
+ }
3904
+ return await llmExecutionTools.callImageGenerationModel(prompt);
3883
3905
  // <- case [🤖]:
3884
3906
  default:
3885
3907
  throw new UnexpectedError(`Unknown model variant "${prompt.modelRequirements.modelVariant}" in ${llmExecutionTools.title}`);
@@ -6305,8 +6327,9 @@
6305
6327
  $ongoingTaskResult.$resultString = $ongoingTaskResult.$completionResult.content;
6306
6328
  break variant;
6307
6329
  case 'EMBEDDING':
6330
+ case 'IMAGE_GENERATION':
6308
6331
  throw new PipelineExecutionError(spaceTrim$1.spaceTrim((block) => `
6309
- Embedding model can not be used in pipeline
6332
+ ${modelRequirements.modelVariant} model can not be used in pipeline
6310
6333
 
6311
6334
  This should be catched during parsing
6312
6335
 
@@ -7965,6 +7988,114 @@
7965
7988
  * Note: [💞] Ignore a discrepancy between file name and entity name
7966
7989
  */
7967
7990
 
7991
+ /**
7992
+ * DICTIONARY commitment definition
7993
+ *
7994
+ * The DICTIONARY commitment defines specific terms and their meanings that the agent should use correctly
7995
+ * in its reasoning and responses. This ensures consistent terminology usage.
7996
+ *
7997
+ * Key features:
7998
+ * - Multiple DICTIONARY commitments are automatically merged into one
7999
+ * - Content is placed in a dedicated section of the system message
8000
+ * - Terms and definitions are stored in metadata.DICTIONARY for debugging
8001
+ * - Agent should use the defined terms correctly in responses
8002
+ *
8003
+ * Example usage in agent source:
8004
+ *
8005
+ * ```book
8006
+ * Legal Assistant
8007
+ *
8008
+ * PERSONA You are a knowledgeable legal assistant
8009
+ * DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
8010
+ * DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
8011
+ * DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
8012
+ * ```
8013
+ *
8014
+ * @private [🪔] Maybe export the commitments through some package
8015
+ */
8016
+ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
8017
+ constructor() {
8018
+ super('DICTIONARY');
8019
+ }
8020
+ /**
8021
+ * Short one-line description of DICTIONARY.
8022
+ */
8023
+ get description() {
8024
+ return 'Define terms and their meanings for consistent terminology usage.';
8025
+ }
8026
+ /**
8027
+ * Icon for this commitment.
8028
+ */
8029
+ get icon() {
8030
+ return '📚';
8031
+ }
8032
+ /**
8033
+ * Markdown documentation for DICTIONARY commitment.
8034
+ */
8035
+ get documentation() {
8036
+ return spaceTrim$1.spaceTrim(`
8037
+ # DICTIONARY
8038
+
8039
+ Defines specific terms and their meanings that the agent should use correctly in reasoning and responses.
8040
+
8041
+ ## Key aspects
8042
+
8043
+ - Multiple \`DICTIONARY\` commitments are merged together.
8044
+ - Terms are defined in the format: "Term is definition"
8045
+ - The agent should use these terms consistently in responses.
8046
+ - Definitions help ensure accurate and consistent terminology.
8047
+
8048
+ ## Examples
8049
+
8050
+ \`\`\`book
8051
+ Legal Assistant
8052
+
8053
+ PERSONA You are a knowledgeable legal assistant specializing in criminal law
8054
+ DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
8055
+ DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
8056
+ DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
8057
+ \`\`\`
8058
+
8059
+ \`\`\`book
8060
+ Medical Assistant
8061
+
8062
+ PERSONA You are a helpful medical assistant
8063
+ DICTIONARY Hypertension is persistently high blood pressure
8064
+ DICTIONARY Diabetes is a chronic condition that affects how the body processes blood sugar
8065
+ DICTIONARY Vaccine is a biological preparation that provides active immunity to a particular disease
8066
+ \`\`\`
8067
+ `);
8068
+ }
8069
+ applyToAgentModelRequirements(requirements, content) {
8070
+ var _a;
8071
+ const trimmedContent = content.trim();
8072
+ if (!trimmedContent) {
8073
+ return requirements;
8074
+ }
8075
+ // Get existing dictionary entries from metadata
8076
+ const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
8077
+ // Merge the new dictionary entry with existing entries
8078
+ const mergedDictionary = existingDictionary
8079
+ ? `${existingDictionary}\n${trimmedContent}`
8080
+ : trimmedContent;
8081
+ // Store the merged dictionary in metadata for debugging and inspection
8082
+ const updatedMetadata = {
8083
+ ...requirements.metadata,
8084
+ DICTIONARY: mergedDictionary,
8085
+ };
8086
+ // Create the dictionary section for the system message
8087
+ // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
8088
+ const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
8089
+ return {
8090
+ ...this.appendToSystemMessage(requirements, dictionarySection),
8091
+ metadata: updatedMetadata,
8092
+ };
8093
+ }
8094
+ }
8095
+ /**
8096
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8097
+ */
8098
+
7968
8099
  /**
7969
8100
  * FORMAT commitment definition
7970
8101
  *
@@ -10785,6 +10916,7 @@
10785
10916
  new DeleteCommitmentDefinition('CANCEL'),
10786
10917
  new DeleteCommitmentDefinition('DISCARD'),
10787
10918
  new DeleteCommitmentDefinition('REMOVE'),
10919
+ new DictionaryCommitmentDefinition(),
10788
10920
  new OpenCommitmentDefinition(),
10789
10921
  new ClosedCommitmentDefinition(),
10790
10922
  new UseBrowserCommitmentDefinition(),
@@ -10936,17 +11068,64 @@
10936
11068
  };
10937
11069
  }
10938
11070
  const lines = agentSource.split('\n');
10939
- const agentName = (((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.trim()) || null);
11071
+ let agentName = null;
11072
+ let agentNameLineIndex = -1;
11073
+ // Find the agent name: first non-empty line that is not a commitment and not a horizontal line
11074
+ for (let i = 0; i < lines.length; i++) {
11075
+ const line = lines[i];
11076
+ if (line === undefined) {
11077
+ continue;
11078
+ }
11079
+ const trimmed = line.trim();
11080
+ if (!trimmed) {
11081
+ continue;
11082
+ }
11083
+ const isHorizontal = HORIZONTAL_LINE_PATTERN.test(line);
11084
+ if (isHorizontal) {
11085
+ continue;
11086
+ }
11087
+ let isCommitment = false;
11088
+ for (const definition of COMMITMENT_REGISTRY) {
11089
+ const typeRegex = definition.createTypeRegex();
11090
+ const match = typeRegex.exec(trimmed);
11091
+ if (match && ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.type)) {
11092
+ isCommitment = true;
11093
+ break;
11094
+ }
11095
+ }
11096
+ if (!isCommitment) {
11097
+ agentName = trimmed;
11098
+ agentNameLineIndex = i;
11099
+ break;
11100
+ }
11101
+ }
10940
11102
  const commitments = [];
10941
11103
  const nonCommitmentLines = [];
10942
- // Always add the first line (agent name) to non-commitment lines
10943
- if (lines[0] !== undefined) {
10944
- nonCommitmentLines.push(lines[0]);
11104
+ // Add lines before agentName that are horizontal lines (they are non-commitment)
11105
+ for (let i = 0; i < agentNameLineIndex; i++) {
11106
+ const line = lines[i];
11107
+ if (line === undefined) {
11108
+ continue;
11109
+ }
11110
+ const trimmed = line.trim();
11111
+ if (!trimmed) {
11112
+ continue;
11113
+ }
11114
+ const isHorizontal = HORIZONTAL_LINE_PATTERN.test(line);
11115
+ if (isHorizontal) {
11116
+ nonCommitmentLines.push(line);
11117
+ }
11118
+ // Note: Commitments before agentName are not added to nonCommitmentLines
11119
+ }
11120
+ // Add the agent name line to non-commitment lines
11121
+ if (agentNameLineIndex >= 0) {
11122
+ nonCommitmentLines.push(lines[agentNameLineIndex]);
10945
11123
  }
10946
11124
  // Parse commitments with multiline support
10947
11125
  let currentCommitment = null;
10948
- // Process lines starting from the second line (skip agent name)
10949
- for (let i = 1; i < lines.length; i++) {
11126
+ // Process lines starting from after the agent name line
11127
+ const startIndex = agentNameLineIndex >= 0 ? agentNameLineIndex + 1 : 0;
11128
+ for (let i = startIndex; i < lines.length; i++) {
10950
11129
  const line = lines[i];
10951
11130
  if (line === undefined) {
10952
11131
  continue;
@@ -11166,7 +11345,12 @@
11166
11345
  };
11167
11346
  }
11168
11347
  // Apply each commitment in order using reduce-like pattern
11169
- for (const commitment of filteredCommitments) {
11348
+ for (let i = 0; i < filteredCommitments.length; i++) {
11349
+ const commitment = filteredCommitments[i];
11350
+ // CLOSED commitment should work only if its the last commitment in the book
11351
+ if (commitment.type === 'CLOSED' && i !== filteredCommitments.length - 1) {
11352
+ continue;
11353
+ }
11170
11354
  const definition = getCommitmentDefinition(commitment.type);
11171
11355
  if (definition) {
11172
11356
  try {
@@ -11261,44 +11445,6 @@
11261
11445
  * TODO: [🌺] Use some intermediate util splitWords
11262
11446
  */
11263
11447
 
11264
- /**
11265
- * Generates a gravatar URL based on agent name for fallback avatar
11266
- *
11267
- * @param agentName The agent name to generate avatar for
11268
- * @returns Gravatar URL
11269
- *
11270
- * @private - [🤹] The fact that profile image is Gravatar is just implementation detail which should be hidden for consumer
11271
- */
11272
- function generateGravatarUrl(agentName) {
11273
- // Use a default name if none provided
11274
- const safeName = agentName || 'Anonymous Agent';
11275
- // Create a simple hash from the name for consistent avatar
11276
- let hash = 0;
11277
- for (let i = 0; i < safeName.length; i++) {
11278
- const char = safeName.charCodeAt(i);
11279
- hash = (hash << 5) - hash + char;
11280
- hash = hash & hash; // Convert to 32bit integer
11281
- }
11282
- const avatarId = Math.abs(hash).toString();
11283
- return `https://www.gravatar.com/avatar/${avatarId}?default=robohash&size=200&rating=x`;
11284
- }
11285
-
11286
- /**
11287
- * Generates an image for the agent to use as profile image
11288
- *
11289
- * @param agentName The agent name to generate avatar for
11290
- * @returns The placeholder profile image URL for the agent
11291
- *
11292
- * @public exported from `@promptbook/core`
11293
- */
11294
- function generatePlaceholderAgentProfileImageUrl(agentName) {
11295
- // Note: [🤹] The fact that profile image is Gravatar is just implementation detail which should be hidden for consumer
11296
- return generateGravatarUrl(agentName);
11297
- }
11298
- /**
11299
- * TODO: [🤹] Figure out best placeholder image generator https://i.pravatar.cc/1000?u=568
11300
- */
11301
-
11302
11448
  /**
11303
11449
  * Creates a Mermaid graph based on the promptbook
11304
11450
  *
@@ -11469,13 +11615,14 @@
11469
11615
  *
11470
11616
  * @public exported from `@promptbook/utils`
11471
11617
  */
11472
- const $isRunningInBrowser = new Function(`
11473
- try {
11474
- return this === window;
11475
- } catch (e) {
11476
- return false;
11618
+ function $isRunningInBrowser() {
11619
+ try {
11620
+ return typeof window !== 'undefined' && typeof window.document !== 'undefined';
11621
+ }
11622
+ catch (e) {
11623
+ return false;
11624
+ }
11477
11625
  }
11478
- `);
11479
11626
  /**
11480
11627
  * TODO: [🎺]
11481
11628
  */
@@ -11487,13 +11634,15 @@
11487
11634
  *
11488
11635
  * @public exported from `@promptbook/utils`
11489
11636
  */
11490
- const $isRunningInJest = new Function(`
11491
- try {
11492
- return process.env.JEST_WORKER_ID !== undefined;
11493
- } catch (e) {
11494
- return false;
11637
+ function $isRunningInJest() {
11638
+ var _a;
11639
+ try {
11640
+ return typeof process !== 'undefined' && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.JEST_WORKER_ID) !== undefined;
11641
+ }
11642
+ catch (e) {
11643
+ return false;
11644
+ }
11495
11645
  }
11496
- `);
11497
11646
  /**
11498
11647
  * TODO: [🎺]
11499
11648
  */
@@ -11505,13 +11654,14 @@
11505
11654
  *
11506
11655
  * @public exported from `@promptbook/utils`
11507
11656
  */
11508
- const $isRunningInNode = new Function(`
11509
- try {
11510
- return this === global;
11511
- } catch (e) {
11512
- return false;
11657
+ function $isRunningInNode() {
11658
+ try {
11659
+ return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
11660
+ }
11661
+ catch (e) {
11662
+ return false;
11663
+ }
11513
11664
  }
11514
- `);
11515
11665
  /**
11516
11666
  * TODO: [🎺]
11517
11667
  */
@@ -11523,17 +11673,17 @@
11523
11673
  *
11524
11674
  * @public exported from `@promptbook/utils`
11525
11675
  */
11526
- const $isRunningInWebWorker = new Function(`
11527
- try {
11528
- if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
11529
- return true;
11530
- } else {
11676
+ function $isRunningInWebWorker() {
11677
+ try {
11678
+ // Note: Check for importScripts which is specific to workers
11679
+ // and not available in the main browser thread
11680
+ return (typeof self !== 'undefined' &&
11681
+ typeof self.importScripts === 'function');
11682
+ }
11683
+ catch (e) {
11531
11684
  return false;
11532
11685
  }
11533
- } catch (e) {
11534
- return false;
11535
11686
  }
11536
- `);
11537
11687
  /**
11538
11688
  * TODO: [🎺]
11539
11689
  */
@@ -11776,10 +11926,6 @@
11776
11926
  const metaType = normalizeTo_camelCase(metaTypeRaw);
11777
11927
  meta[metaType] = spaceTrim__default["default"](commitment.content.substring(metaTypeRaw.length));
11778
11928
  }
11779
- // Generate gravatar fallback if no meta image specified
11780
- if (!meta.image) {
11781
- meta.image = generatePlaceholderAgentProfileImageUrl(parseResult.agentName || '!!');
11782
- }
11783
11929
  // Generate fullname fallback if no meta fullname specified
11784
11930
  if (!meta.fullname) {
11785
11931
  meta.fullname = parseResult.agentName || createDefaultAgentName(agentSource);
@@ -11791,6 +11937,7 @@
11791
11937
  return {
11792
11938
  agentName: normalizeAgentName(parseResult.agentName || createDefaultAgentName(agentSource)),
11793
11939
  agentHash,
11940
+ permanentId: meta.id,
11794
11941
  personaDescription,
11795
11942
  initialMessage,
11796
11943
  meta,
@@ -11982,6 +12129,59 @@
11982
12129
  // <- [🐱‍🚀] Buttons into genesis book
11983
12130
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
11984
12131
 
12132
+ /**
12133
+ * Generates an image for the agent to use as profile image
12134
+ *
12135
+ * @param agentId - The permanent ID of the agent
12136
+ * @returns The placeholder profile image URL for the agent
12137
+ *
12138
+ * @public exported from `@promptbook/core`
12139
+ */
12140
+ function generatePlaceholderAgentProfileImageUrl(agentIdOrName, agentsServerUrl = CORE_SERVER.urls[0]) {
12141
+ if (typeof agentsServerUrl === 'string') {
12142
+ agentsServerUrl = new URL(agentsServerUrl);
12143
+ }
12144
+ return `${agentsServerUrl.href}agents/${agentIdOrName}/images/default-avatar.png`;
12145
+ }
12146
+ /**
12147
+ * TODO: [🤹] Figure out best placeholder image generator https://i.pravatar.cc/1000?u=568
12148
+ */
12149
+
12150
+ /**
12151
+ * Base58 characters
12152
+ */
12153
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
12154
+ /**
12155
+ * Generates random base58 string
12156
+ *
12157
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
12158
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
12159
+ *
12160
+ * @param length - length of the string
12161
+ * @returns secure random base58 string
12162
+ *
12163
+ * @private internal helper function
12164
+ */
12165
+ function $randomBase58(length) {
12166
+ let result = '';
12167
+ while (result.length < length) {
12168
+ // Generate enough bytes to cover the remaining length, plus some extra buffer to reduce calls
12169
+ // But simply generating `length - result.length` is fine for small lengths
12170
+ const bytes = crypto.randomBytes(length - result.length);
12171
+ for (let i = 0; i < bytes.length; i++) {
12172
+ const byte = bytes[i];
12173
+ // 58 * 4 = 232
12174
+ // We discard values >= 232 to avoid modulo bias
12175
+ if (byte < 232) {
12176
+ result += BASE58_ALPHABET[byte % 58];
12177
+ if (result.length === length)
12178
+ break;
12179
+ }
12180
+ }
12181
+ }
12182
+ return result;
12183
+ }
12184
+
11985
12185
  // import { getTableName } from '../../../../../apps/agents-server/src/database/getTableName';
11986
12186
  // <- TODO: [🐱‍🚀] Prevent imports from `/apps` -> `/src`
11987
12187
  /**
@@ -12015,19 +12215,20 @@
12015
12215
  const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
12016
12216
  const selectResult = await this.supabaseClient
12017
12217
  .from(this.getTableName('Agent'))
12018
- .select('agentName,agentProfile');
12218
+ .select('agentName,agentProfile,permanentId')
12219
+ .is('deletedAt', null);
12019
12220
  if (selectResult.error) {
12020
12221
  throw new DatabaseError(spaceTrim((block) => `
12021
-
12222
+
12022
12223
  Error fetching agents from Supabase:
12023
-
12224
+
12024
12225
  ${block(selectResult.error.message)}
12025
12226
  `));
12026
12227
  }
12027
12228
  if (isVerbose) {
12028
12229
  console.info(`Found ${selectResult.data.length} agents in directory`);
12029
12230
  }
12030
- return selectResult.data.map(({ agentName, agentProfile }) => {
12231
+ return selectResult.data.map(({ agentName, agentProfile, permanentId }) => {
12031
12232
  if (isVerbose && agentProfile.agentName !== agentName) {
12032
12233
  console.warn(spaceTrim(`
12033
12234
  Agent name mismatch for agent "${agentName}". Using name from database.
@@ -12039,26 +12240,42 @@
12039
12240
  return {
12040
12241
  ...agentProfile,
12041
12242
  agentName,
12243
+ permanentId: permanentId || agentProfile.permanentId,
12042
12244
  };
12043
12245
  });
12044
12246
  }
12045
12247
  /**
12046
12248
  * [🐱‍🚀]@@@
12047
12249
  */
12048
- async getAgentSource(agentName) {
12250
+ async getAgentPermanentId(agentNameOrPermanentId) {
12251
+ const selectResult = await this.supabaseClient
12252
+ .from(this.getTableName('Agent'))
12253
+ .select('permanentId')
12254
+ .or(`agentName.eq.${agentNameOrPermanentId},permanentId.eq.${agentNameOrPermanentId}`)
12255
+ .single();
12256
+ if (selectResult.error || !selectResult.data) {
12257
+ throw new NotFoundError(`Agent with name not id "${agentNameOrPermanentId}" not found`);
12258
+ }
12259
+ return selectResult.data.permanentId;
12260
+ }
12261
+ /**
12262
+ * [🐱‍🚀]@@@
12263
+ */
12264
+ async getAgentSource(agentNameOrPermanentId) {
12049
12265
  const selectResult = await this.supabaseClient
12050
12266
  .from(this.getTableName('Agent'))
12051
12267
  .select('agentSource')
12052
- .eq('agentName', agentName);
12268
+ .or(`agentName.eq.${agentNameOrPermanentId},permanentId.eq.${agentNameOrPermanentId}`)
12269
+ .is('deletedAt', null);
12053
12270
  if (selectResult.data && selectResult.data.length === 0) {
12054
- throw new NotFoundError(`Agent "${agentName}" not found`);
12271
+ throw new NotFoundError(`Agent "${agentNameOrPermanentId}" not found`);
12055
12272
  }
12056
12273
  else if (selectResult.data && selectResult.data.length > 1) {
12057
- throw new UnexpectedError(`More agents with agentName="${agentName}" found`);
12274
+ throw new UnexpectedError(`More agents with name or id "${agentNameOrPermanentId}" found`);
12058
12275
  }
12059
12276
  else if (selectResult.error) {
12060
12277
  throw new DatabaseError(spaceTrim((block) => `
12061
- Error fetching agent "${agentName}" from Supabase:
12278
+ Error fetching agent "${agentNameOrPermanentId}" from Supabase:
12062
12279
 
12063
12280
  ${block(selectResult.error.message)}
12064
12281
  `));
@@ -12071,12 +12288,26 @@
12071
12288
  * Note: You can set 'PARENT' in the agent source to inherit from another agent in the collection.
12072
12289
  */
12073
12290
  async createAgent(agentSource) {
12074
- const agentProfile = parseAgentSource(agentSource);
12291
+ let agentProfile = parseAgentSource(agentSource);
12075
12292
  // <- TODO: [🕛]
12293
+ // 1. Extract permanentId from the source if present
12294
+ let { permanentId } = agentProfile;
12295
+ // 2. Remove META ID from the source
12296
+ const lines = agentSource.split('\n');
12297
+ const strippedLines = lines.filter((line) => !line.trim().startsWith('META ID '));
12298
+ if (lines.length !== strippedLines.length) {
12299
+ agentSource = strippedLines.join('\n');
12300
+ // 3. Re-parse the agent source to get the correct hash and other info
12301
+ agentProfile = parseAgentSource(agentSource);
12302
+ }
12076
12303
  const { agentName, agentHash } = agentProfile;
12304
+ if (!permanentId) {
12305
+ permanentId = $randomBase58(14);
12306
+ }
12077
12307
  const insertAgentResult = await this.supabaseClient.from(this.getTableName('Agent')).insert({
12078
12308
  agentName,
12079
12309
  agentHash,
12310
+ permanentId,
12080
12311
  agentProfile,
12081
12312
  createdAt: new Date().toISOString(),
12082
12313
  updatedAt: null,
@@ -12094,27 +12325,29 @@
12094
12325
  await this.supabaseClient.from(this.getTableName('AgentHistory')).insert({
12095
12326
  createdAt: new Date().toISOString(),
12096
12327
  agentName,
12328
+ permanentId,
12097
12329
  agentHash,
12098
12330
  previousAgentHash: null,
12099
12331
  agentSource,
12100
12332
  promptbookEngineVersion: PROMPTBOOK_ENGINE_VERSION,
12101
12333
  });
12102
12334
  // <- TODO: [🧠] What to do with `insertAgentHistoryResult.error`, ignore? wait?
12103
- return agentProfile;
12335
+ return { ...agentProfile, permanentId };
12104
12336
  }
12105
12337
  /**
12106
12338
  * Updates an existing agent in the collection
12107
12339
  */
12108
- async updateAgentSource(agentName, agentSource) {
12340
+ async updateAgentSource(permanentId, agentSource) {
12341
+ console.log('!!! updateAgentSource', { permanentId });
12109
12342
  const selectPreviousAgentResult = await this.supabaseClient
12110
12343
  .from(this.getTableName('Agent'))
12111
- .select('agentHash,agentName')
12112
- .eq('agentName', agentName)
12344
+ .select('agentHash,agentName,permanentId')
12345
+ .eq('permanentId', permanentId)
12113
12346
  .single();
12114
12347
  if (selectPreviousAgentResult.error) {
12115
12348
  throw new DatabaseError(spaceTrim((block) => `
12116
12349
 
12117
- Error fetching agent "${agentName}" from Supabase:
12350
+ Error fetching agent "${permanentId}" from Supabase:
12118
12351
 
12119
12352
  ${block(selectPreviousAgentResult.error.message)}
12120
12353
  `));
@@ -12122,26 +12355,48 @@
12122
12355
  }
12123
12356
  selectPreviousAgentResult.data.agentName;
12124
12357
  const previousAgentHash = selectPreviousAgentResult.data.agentHash;
12125
- const agentProfile = parseAgentSource(agentSource);
12358
+ const previousPermanentId = selectPreviousAgentResult.data.permanentId;
12359
+ let agentProfile = parseAgentSource(agentSource);
12126
12360
  // <- TODO: [🕛]
12127
- const { agentHash } = agentProfile;
12361
+ // 1. Extract permanentId from the source if present
12362
+ let { permanentId: newPermanentId } = agentProfile;
12363
+ // 2. Remove META ID from the source
12364
+ const lines = agentSource.split('\n');
12365
+ const strippedLines = lines.filter((line) => !line.trim().startsWith('META ID '));
12366
+ if (lines.length !== strippedLines.length) {
12367
+ agentSource = strippedLines.join('\n');
12368
+ // 3. Re-parse the agent source to get the correct hash and other info
12369
+ agentProfile = parseAgentSource(agentSource);
12370
+ }
12371
+ const { agentHash, agentName } = agentProfile;
12372
+ if (!newPermanentId && previousPermanentId) {
12373
+ newPermanentId = previousPermanentId;
12374
+ }
12375
+ if (!newPermanentId) {
12376
+ newPermanentId = $randomBase58(14);
12377
+ }
12378
+ if (newPermanentId !== permanentId) {
12379
+ // [🧠] Should be allowed to change permanentId?
12380
+ throw new UnexpectedError(`Permanent ID mismatch: "${permanentId}" (argument) !== "${newPermanentId}" (in source)`);
12381
+ }
12128
12382
  const updateAgentResult = await this.supabaseClient
12129
12383
  .from(this.getTableName('Agent'))
12130
12384
  .update({
12131
12385
  // TODO: [🐱‍🚀] Compare not update> agentName: agentProfile.agentName || '[🐱‍🚀]' /* <- TODO: [🐱‍🚀] Remove */,
12386
+ permanentId,
12132
12387
  agentProfile,
12133
12388
  updatedAt: new Date().toISOString(),
12134
12389
  agentHash: agentProfile.agentHash,
12135
12390
  agentSource,
12136
12391
  promptbookEngineVersion: PROMPTBOOK_ENGINE_VERSION,
12137
12392
  })
12138
- .eq('agentName', agentName);
12393
+ .eq('permanentId', permanentId);
12139
12394
  // console.log('[🐱‍🚀] updateAgent', updateResult);
12140
12395
  // console.log('[🐱‍🚀] old', oldAgentSource);
12141
12396
  // console.log('[🐱‍🚀] new', newAgentSource);
12142
12397
  if (updateAgentResult.error) {
12143
12398
  throw new DatabaseError(spaceTrim((block) => `
12144
- Error updating agent "${agentName}" in Supabase:
12399
+ Error updating agent "${permanentId}" in Supabase:
12145
12400
 
12146
12401
  ${block(updateAgentResult.error.message)}
12147
12402
  `));
@@ -12149,6 +12404,7 @@
12149
12404
  await this.supabaseClient.from(this.getTableName('AgentHistory')).insert({
12150
12405
  createdAt: new Date().toISOString(),
12151
12406
  agentName,
12407
+ permanentId,
12152
12408
  agentHash,
12153
12409
  previousAgentHash,
12154
12410
  agentSource,
@@ -12156,101 +12412,119 @@
12156
12412
  });
12157
12413
  // <- TODO: [🧠] What to do with `insertAgentHistoryResult.error`, ignore? wait?
12158
12414
  }
12159
- // TODO: [🐱‍🚀] public async getAgentSourceSubject(agentName: string_agent_name): Promise<BehaviorSubject<string_book>>
12415
+ // TODO: [🐱‍🚀] public async getAgentSourceSubject(permanentId: string_agent_permanent_id): Promise<BehaviorSubject<string_book>>
12160
12416
  // Use Supabase realtime logic
12161
12417
  /**
12162
- * Deletes an agent from the collection
12418
+ * List agents that are soft deleted (deletedAt IS NOT NULL)
12163
12419
  */
12164
- async deleteAgent(agentName) {
12165
- const deleteResult = await this.supabaseClient
12420
+ async listDeletedAgents() {
12421
+ const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
12422
+ const selectResult = await this.supabaseClient
12166
12423
  .from(this.getTableName('Agent'))
12167
- .delete()
12168
- .eq('agentName', agentName);
12169
- if (deleteResult.error) {
12424
+ .select('agentName,agentProfile,permanentId')
12425
+ .not('deletedAt', 'is', null);
12426
+ if (selectResult.error) {
12170
12427
  throw new DatabaseError(spaceTrim((block) => `
12171
- Error deleting agent "${agentName}" from Supabase:
12172
-
12173
- ${block(deleteResult.error.message)}
12174
- `));
12428
+ Error fetching deleted agents from Supabase:
12429
+
12430
+ ${block(selectResult.error.message)}
12431
+ `));
12432
+ }
12433
+ if (isVerbose) {
12434
+ console.info(`Found ${selectResult.data.length} deleted agents in directory`);
12175
12435
  }
12436
+ return selectResult.data.map(({ agentName, agentProfile, permanentId }) => {
12437
+ if (isVerbose && agentProfile.agentName !== agentName) {
12438
+ console.warn(spaceTrim(`
12439
+ Agent name mismatch for agent "${agentName}". Using name from database.
12440
+
12441
+ agentName: "${agentName}"
12442
+ agentProfile.agentName: "${agentProfile.agentName}"
12443
+ `));
12444
+ }
12445
+ return {
12446
+ ...agentProfile,
12447
+ agentName,
12448
+ permanentId: permanentId || agentProfile.permanentId,
12449
+ };
12450
+ });
12176
12451
  }
12177
12452
  /**
12178
12453
  * List history of an agent
12179
12454
  */
12180
- async listAgentHistory(agentName) {
12455
+ async listAgentHistory(permanentId) {
12181
12456
  const result = await this.supabaseClient
12182
12457
  .from(this.getTableName('AgentHistory'))
12183
12458
  .select('id, createdAt, agentHash, promptbookEngineVersion')
12184
- .eq('agentName', agentName)
12459
+ .eq('permanentId', permanentId)
12185
12460
  .order('createdAt', { ascending: false });
12186
12461
  if (result.error) {
12187
12462
  throw new DatabaseError(spaceTrim((block) => `
12188
- Error listing history for agent "${agentName}" from Supabase:
12189
-
12463
+ Error listing history for agent "${permanentId}" from Supabase:
12464
+
12190
12465
  ${block(result.error.message)}
12191
12466
  `));
12192
12467
  }
12193
12468
  return result.data;
12194
12469
  }
12195
12470
  /**
12196
- * List agents that are in history but not in the active agents list
12471
+ * Restore a soft-deleted agent by setting deletedAt to NULL
12197
12472
  */
12198
- async listDeletedAgents() {
12199
- const historyNamesResult = await this.supabaseClient.from(this.getTableName('AgentHistory')).select('agentName');
12200
- const currentNamesResult = await this.supabaseClient.from(this.getTableName('Agent')).select('agentName');
12201
- if (historyNamesResult.error) {
12202
- throw new DatabaseError(spaceTrim((block) => `
12203
- Error fetching agent history names from Supabase:
12204
-
12205
- ${block(historyNamesResult.error.message)}
12206
- `));
12207
- }
12208
- if (currentNamesResult.error) {
12473
+ async restoreAgent(permanentId) {
12474
+ const updateResult = await this.supabaseClient
12475
+ .from(this.getTableName('Agent'))
12476
+ .update({ deletedAt: null })
12477
+ .eq('permanentId', permanentId)
12478
+ .not('deletedAt', 'is', null);
12479
+ if (updateResult.error) {
12209
12480
  throw new DatabaseError(spaceTrim((block) => `
12210
- Error fetching current agent names from Supabase:
12211
-
12212
- ${block(currentNamesResult.error.message)}
12481
+ Error restoring agent "${permanentId}" from Supabase:
12482
+
12483
+ ${block(updateResult.error.message)}
12213
12484
  `));
12214
12485
  }
12215
- const currentNames = new Set(currentNamesResult.data.map((d) => d.agentName));
12216
- const deletedNames = new Set();
12217
- for (const { agentName } of historyNamesResult.data) {
12218
- if (!currentNames.has(agentName)) {
12219
- deletedNames.add(agentName);
12220
- }
12221
- }
12222
- return Array.from(deletedNames);
12223
12486
  }
12224
12487
  /**
12225
- * Restore an agent from history
12488
+ * Restore an agent from a specific history entry
12489
+ *
12490
+ * This will update the current agent with the source from the history entry
12226
12491
  */
12227
- async restoreAgent(historyId) {
12492
+ async restoreAgentFromHistory(historyId) {
12493
+ // First, get the history entry
12228
12494
  const historyResult = await this.supabaseClient
12229
12495
  .from(this.getTableName('AgentHistory'))
12230
- .select('*')
12496
+ .select('permanentId, agentSource')
12231
12497
  .eq('id', historyId)
12232
12498
  .single();
12233
12499
  if (historyResult.error) {
12234
12500
  throw new DatabaseError(spaceTrim((block) => `
12235
- Error fetching agent history item "${historyId}" from Supabase:
12236
-
12501
+ Error fetching history entry with id "${historyId}" from Supabase:
12502
+
12237
12503
  ${block(historyResult.error.message)}
12238
12504
  `));
12239
12505
  }
12240
- const { agentName, agentSource } = historyResult.data;
12241
- // Check if agent exists
12242
- const agentResult = await this.supabaseClient
12243
- .from(this.getTableName('Agent'))
12244
- .select('id')
12245
- .eq('agentName', agentName)
12246
- .single();
12247
- if (agentResult.data) {
12248
- // Update
12249
- await this.updateAgentSource(agentName, agentSource);
12506
+ if (!historyResult.data) {
12507
+ throw new NotFoundError(`History entry with id "${historyId}" not found`);
12250
12508
  }
12251
- else {
12252
- // Insert (Restore from deleted)
12253
- await this.createAgent(agentSource);
12509
+ const { permanentId, agentSource } = historyResult.data;
12510
+ // Update the agent with the source from the history entry
12511
+ await this.updateAgentSource(permanentId, agentSource);
12512
+ }
12513
+ /**
12514
+ * Soft delete an agent by setting deletedAt to current timestamp
12515
+ */
12516
+ async deleteAgent(permanentId) {
12517
+ const updateResult = await this.supabaseClient
12518
+ .from(this.getTableName('Agent'))
12519
+ .update({ deletedAt: new Date().toISOString() })
12520
+ .eq('permanentId', permanentId)
12521
+ .is('deletedAt', null);
12522
+ if (updateResult.error) {
12523
+ throw new DatabaseError(spaceTrim((block) => `
12524
+ Error deleting agent "${permanentId}" from Supabase:
12525
+
12526
+ ${block(updateResult.error.message)}
12527
+ `));
12254
12528
  }
12255
12529
  }
12256
12530
  /**
@@ -13940,11 +14214,7 @@
13940
14214
  // TODO: [🚜] DRY
13941
14215
  if ($taskJson.modelRequirements[command.key] !== undefined) {
13942
14216
  if ($taskJson.modelRequirements[command.key] === command.value) {
13943
- console.warn(`Multiple commands \`MODEL ${{
13944
- modelName: 'NAME',
13945
- modelVariant: 'VARIANT',
13946
- maxTokens: '???',
13947
- }[command.key]} ${command.value}\` in the task "${$taskJson.title || $taskJson.name}"`);
14217
+ console.warn(`Multiple commands \`MODEL ${command.key} ${command.value}\` in the task "${$taskJson.title || $taskJson.name}"`);
13948
14218
  // <- TODO: [🏮] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
13949
14219
  }
13950
14220
  else {
@@ -16468,7 +16738,7 @@
16468
16738
  ${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
16469
16739
  ${morePieces.join('; ')}
16470
16740
  `);
16471
- if ($isRunningInNode) {
16741
+ if ($isRunningInNode()) {
16472
16742
  if (isInstalled && isFullyConfigured) {
16473
16743
  providerMessage = colors__default["default"].green(providerMessage);
16474
16744
  }
@@ -16673,6 +16943,9 @@
16673
16943
  case 'EMBEDDING':
16674
16944
  promptResult = await llmTools.callEmbeddingModel(prompt);
16675
16945
  break variant;
16946
+ case 'IMAGE_GENERATION':
16947
+ promptResult = await llmTools.callImageGenerationModel(prompt);
16948
+ break variant;
16676
16949
  // <- case [🤖]:
16677
16950
  default:
16678
16951
  throw new PipelineExecutionError(`Unknown model variant "${prompt.modelRequirements.modelVariant}"`);
@@ -16709,12 +16982,13 @@
16709
16982
  }
16710
16983
  }
16711
16984
  catch (error) {
16985
+ assertsError(error);
16712
16986
  // If validation throws an unexpected error, don't cache
16713
16987
  shouldCache = false;
16714
16988
  if (isVerbose) {
16715
16989
  console.info('Not caching result due to validation error for key:', key, {
16716
16990
  content: promptResult.content,
16717
- validationError: error instanceof Error ? error.message : String(error),
16991
+ validationError: serializeError(error),
16718
16992
  });
16719
16993
  }
16720
16994
  }
@@ -16760,6 +17034,11 @@
16760
17034
  return /* not await */ callCommonModel(prompt);
16761
17035
  };
16762
17036
  }
17037
+ if (llmTools.callImageGenerationModel !== undefined) {
17038
+ proxyTools.callImageGenerationModel = async (prompt) => {
17039
+ return /* not await */ callCommonModel(prompt);
17040
+ };
17041
+ }
16763
17042
  // <- Note: [🤖]
16764
17043
  return proxyTools;
16765
17044
  }
@@ -16798,6 +17077,11 @@
16798
17077
  throw new LimitReachedError('Cannot call `callEmbeddingModel` because you are not allowed to spend any cost');
16799
17078
  };
16800
17079
  }
17080
+ if (proxyTools.callImageGenerationModel !== undefined) {
17081
+ proxyTools.callImageGenerationModel = async (prompt) => {
17082
+ throw new LimitReachedError('Cannot call `callImageGenerationModel` because you are not allowed to spend any cost');
17083
+ };
17084
+ }
16801
17085
  // <- Note: [🤖]
16802
17086
  return proxyTools;
16803
17087
  }
@@ -17869,7 +18153,7 @@
17869
18153
  let threadMessages = [];
17870
18154
  if ('thread' in prompt && Array.isArray(prompt.thread)) {
17871
18155
  threadMessages = prompt.thread.map((msg) => ({
17872
- role: msg.role === 'assistant' ? 'assistant' : 'user',
18156
+ role: msg.sender === 'assistant' ? 'assistant' : 'user',
17873
18157
  content: msg.content,
17874
18158
  }));
17875
18159
  }
@@ -18282,13 +18566,14 @@
18282
18566
  const modelName = currentModelRequirements.modelName || this.getDefaultImageGenerationModel().modelName;
18283
18567
  const modelSettings = {
18284
18568
  model: modelName,
18285
- // size: currentModelRequirements.size,
18286
- // quality: currentModelRequirements.quality,
18287
- // style: currentModelRequirements.style,
18569
+ size: currentModelRequirements.size,
18570
+ quality: currentModelRequirements.quality,
18571
+ style: currentModelRequirements.style,
18288
18572
  };
18289
18573
  const rawPromptContent = templateParameters(content, { ...parameters, modelName });
18290
18574
  const rawRequest = {
18291
18575
  ...modelSettings,
18576
+ size: modelSettings.size || '1024x1024',
18292
18577
  prompt: rawPromptContent,
18293
18578
  user: (_a = this.options.userId) === null || _a === void 0 ? void 0 : _a.toString(),
18294
18579
  response_format: 'url', // TODO: [🧠] Maybe allow b64_json
@@ -19394,9 +19679,52 @@
19394
19679
  ${block(result.content)}
19395
19680
 
19396
19681
  `);
19682
+ // Extract knowledge
19683
+ let knowledgeBlock = '';
19684
+ try {
19685
+ const extractionPrompt = {
19686
+ title: 'Knowledge Extraction',
19687
+ modelRequirements: {
19688
+ modelVariant: 'CHAT',
19689
+ },
19690
+ content: spaceTrim__default["default"]((block) => `
19691
+ You are an AI agent that is learning from a conversation.
19692
+
19693
+ Here is the conversation so far:
19694
+
19695
+ User: ${block(prompt.content)}
19696
+ Agent: ${block(result.content)}
19697
+
19698
+ Extract any new knowledge, facts, or important information that should be remembered for future interactions.
19699
+ Format the output as a list of KNOWLEDGE blocks.
19700
+ If there is no new knowledge, return nothing.
19701
+
19702
+ Example output:
19703
+ KNOWLEDGE The user's name is Alice.
19704
+ KNOWLEDGE The project deadline is next Friday.
19705
+ `),
19706
+ pipelineUrl: 'https://github.com/webgptorg/promptbook/blob/main/prompts/knowledge-extraction.ptbk.md',
19707
+ parameters: {},
19708
+ };
19709
+ if (this.options.llmTools.callChatModel) {
19710
+ const extractionResult = await this.options.llmTools.callChatModel(extractionPrompt);
19711
+ const extractedContent = extractionResult.content;
19712
+ if (extractedContent.includes('KNOWLEDGE')) {
19713
+ knowledgeBlock = '\n\n' + spaceTrim__default["default"](extractedContent);
19714
+ }
19715
+ }
19716
+ else {
19717
+ // TODO: [🧠] Fallback to callChatModelStream if callChatModel is not available
19718
+ }
19719
+ }
19720
+ catch (error) {
19721
+ if (this.options.isVerbose) {
19722
+ console.warn('Failed to extract knowledge', error);
19723
+ }
19724
+ }
19397
19725
  // Append to the current source
19398
19726
  const currentSource = this.agentSource.value;
19399
- const newSource = padBook(validateBook(spaceTrim__default["default"](currentSource) + '\n\n' + learningExample));
19727
+ const newSource = padBook(validateBook(spaceTrim__default["default"](currentSource) + '\n\n' + learningExample + knowledgeBlock));
19400
19728
  // Update the source (which will trigger the subscription and update the underlying tools)
19401
19729
  this.agentSource.next(newSource);
19402
19730
  return result;
@@ -21187,6 +21515,7 @@
21187
21515
  exports.BoilerplateFormfactorDefinition = BoilerplateFormfactorDefinition;
21188
21516
  exports.CLAIM = CLAIM;
21189
21517
  exports.CLI_APP_ID = CLI_APP_ID;
21518
+ exports.CORE_SERVER = CORE_SERVER;
21190
21519
  exports.CallbackInterfaceTools = CallbackInterfaceTools;
21191
21520
  exports.ChatbotFormfactorDefinition = ChatbotFormfactorDefinition;
21192
21521
  exports.CollectionError = CollectionError;