@promptbook/core 0.103.0-51 → 0.103.0-53

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 (30) hide show
  1. package/esm/index.es.js +657 -88
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/servers.d.ts +8 -1
  4. package/esm/typings/src/_packages/components.index.d.ts +2 -0
  5. package/esm/typings/src/_packages/core.index.d.ts +6 -0
  6. package/esm/typings/src/_packages/types.index.d.ts +2 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +2 -0
  8. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +1 -0
  9. package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +7 -0
  10. package/esm/typings/src/book-2.0/agent-source/createCommitmentRegex.d.ts +2 -2
  11. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +10 -0
  12. package/esm/typings/src/book-components/PromptbookAgent/PromptbookAgent.d.ts +6 -0
  13. package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +12 -0
  14. package/esm/typings/src/book-components/icons/MicIcon.d.ts +8 -0
  15. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +17 -0
  16. package/esm/typings/src/commitments/MESSAGE/AgentMessageCommitmentDefinition.d.ts +28 -0
  17. package/esm/typings/src/commitments/MESSAGE/UserMessageCommitmentDefinition.d.ts +28 -0
  18. package/esm/typings/src/commitments/META_COLOR/META_COLOR.d.ts +38 -0
  19. package/esm/typings/src/commitments/_base/BaseCommitmentDefinition.d.ts +2 -1
  20. package/esm/typings/src/commitments/index.d.ts +22 -1
  21. package/esm/typings/src/execution/LlmExecutionTools.d.ts +9 -0
  22. package/esm/typings/src/llm-providers/agent/Agent.d.ts +1 -0
  23. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +2 -1
  24. package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +10 -1
  25. package/esm/typings/src/utils/normalization/normalizeMessageText.d.ts +9 -0
  26. package/esm/typings/src/utils/normalization/normalizeMessageText.test.d.ts +1 -0
  27. package/esm/typings/src/version.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/umd/index.umd.js +658 -87
  30. package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js CHANGED
@@ -28,12 +28,23 @@
28
28
  * @generated
29
29
  * @see https://github.com/webgptorg/promptbook
30
30
  */
31
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-51';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-53';
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
35
35
  */
36
36
 
37
+ /**
38
+ * Core Promptbook server configuration.
39
+ *
40
+ * This server is also used for auto-federation in the Agents Server.
41
+ */
42
+ const CORE_SERVER = {
43
+ title: 'Promptbook Core',
44
+ description: `Core Promptbook server used for auto-federation`,
45
+ owner: 'AI Web, LLC <legal@ptbk.io> (https://www.ptbk.io/)',
46
+ urls: ['https://core.ptbk.io/'],
47
+ };
37
48
  /**
38
49
  * Available remote servers for the Promptbook
39
50
  *
@@ -55,6 +66,7 @@
55
66
  owner: 'AI Web, LLC <legal@ptbk.io> (https://www.ptbk.io/)',
56
67
  urls: ['https://s6.ptbk.io/'],
57
68
  },
69
+ CORE_SERVER,
58
70
  /*
59
71
  Note: Working on older version of Promptbook and not supported anymore
60
72
  {
@@ -67,7 +79,14 @@
67
79
  */
68
80
  ];
69
81
  /**
70
- * TODO: [🐱‍🚀] Auto-federated server from url in here
82
+ * Remote servers that are auto-federated by the Agents Server.
83
+ *
84
+ * These servers are always added in addition to the `FEDERATED_SERVERS` metadata.
85
+ *
86
+ * @public exported from `@promptbook/core`
87
+ */
88
+ const AUTO_FEDERATED_AGENT_SERVER_URLS = CORE_SERVER.urls;
89
+ /**
71
90
  * Note: [💞] Ignore a discrepancy between file name and entity name
72
91
  */
73
92
 
@@ -7445,9 +7464,13 @@
7445
7464
  *
7446
7465
  * @private - TODO: [🧠] Maybe should be public?
7447
7466
  */
7448
- function createCommitmentRegex(commitment) {
7449
- const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7450
- const keywordPattern = escapedCommitment.split(/\s+/).join('\\s+');
7467
+ function createCommitmentRegex(commitment, aliases = []) {
7468
+ const allCommitments = [commitment, ...aliases];
7469
+ const patterns = allCommitments.map((c) => {
7470
+ const escapedCommitment = c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7471
+ return escapedCommitment.split(/\s+/).join('\\s+');
7472
+ });
7473
+ const keywordPattern = patterns.join('|');
7451
7474
  const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b\\s+(?<contents>.+)$`, 'gim');
7452
7475
  return regex;
7453
7476
  }
@@ -7460,9 +7483,13 @@
7460
7483
  *
7461
7484
  * @private
7462
7485
  */
7463
- function createCommitmentTypeRegex(commitment) {
7464
- const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7465
- const keywordPattern = escapedCommitment.split(/\s+/).join('\\s+');
7486
+ function createCommitmentTypeRegex(commitment, aliases = []) {
7487
+ const allCommitments = [commitment, ...aliases];
7488
+ const patterns = allCommitments.map((c) => {
7489
+ const escapedCommitment = c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7490
+ return escapedCommitment.split(/\s+/).join('\\s+');
7491
+ });
7492
+ const keywordPattern = patterns.join('|');
7466
7493
  const regex = new RegExp(`^\\s*(?<type>${keywordPattern})\\b`, 'gim');
7467
7494
  return regex;
7468
7495
  }
@@ -7474,22 +7501,23 @@
7474
7501
  * @private
7475
7502
  */
7476
7503
  class BaseCommitmentDefinition {
7477
- constructor(type) {
7504
+ constructor(type, aliases = []) {
7478
7505
  this.type = type;
7506
+ this.aliases = aliases;
7479
7507
  }
7480
7508
  /**
7481
7509
  * Creates a regex pattern to match this commitment in agent source
7482
7510
  * Uses the existing createCommitmentRegex function as internal helper
7483
7511
  */
7484
7512
  createRegex() {
7485
- return createCommitmentRegex(this.type);
7513
+ return createCommitmentRegex(this.type, this.aliases);
7486
7514
  }
7487
7515
  /**
7488
7516
  * Creates a regex pattern to match just the commitment type
7489
7517
  * Uses the existing createCommitmentTypeRegex function as internal helper
7490
7518
  */
7491
7519
  createTypeRegex() {
7492
- return createCommitmentTypeRegex(this.type);
7520
+ return createCommitmentTypeRegex(this.type, this.aliases);
7493
7521
  }
7494
7522
  /**
7495
7523
  * Helper method to create a new requirements object with updated system message
@@ -8100,6 +8128,77 @@
8100
8128
  * Note: [💞] Ignore a discrepancy between file name and entity name
8101
8129
  */
8102
8130
 
8131
+ /**
8132
+ * AGENT MESSAGE commitment definition
8133
+ *
8134
+ * The AGENT MESSAGE commitment defines a message from the agent in the conversation history.
8135
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
8136
+ *
8137
+ * Example usage in agent source:
8138
+ *
8139
+ * ```book
8140
+ * AGENT MESSAGE What seems to be the issue?
8141
+ * ```
8142
+ *
8143
+ * @private [🪔] Maybe export the commitments through some package
8144
+ */
8145
+ class AgentMessageCommitmentDefinition extends BaseCommitmentDefinition {
8146
+ constructor() {
8147
+ super('AGENT MESSAGE');
8148
+ }
8149
+ /**
8150
+ * Short one-line description of AGENT MESSAGE.
8151
+ */
8152
+ get description() {
8153
+ return 'Defines a **message from the agent** in the conversation history.';
8154
+ }
8155
+ /**
8156
+ * Markdown documentation for AGENT MESSAGE commitment.
8157
+ */
8158
+ get documentation() {
8159
+ return spaceTrim$1.spaceTrim(`
8160
+ # ${this.type}
8161
+
8162
+ Defines a message from the agent in the conversation history. This is used to pre-fill the chat with a conversation history or to provide few-shot examples.
8163
+
8164
+ ## Key aspects
8165
+
8166
+ - Represents a message sent by the agent.
8167
+ - Used for setting up conversation context.
8168
+ - Can be used in conjunction with USER MESSAGE.
8169
+
8170
+ ## Examples
8171
+
8172
+ \`\`\`book
8173
+ Conversation History
8174
+
8175
+ USER MESSAGE Hello, I have a problem.
8176
+ AGENT MESSAGE What seems to be the issue?
8177
+ USER MESSAGE My computer is not starting.
8178
+ \`\`\`
8179
+ `);
8180
+ }
8181
+ applyToAgentModelRequirements(requirements, content) {
8182
+ // AGENT MESSAGE is for UI display purposes / conversation history construction
8183
+ // and typically doesn't need to be added to the system prompt or model requirements directly.
8184
+ // It is extracted separately for the chat interface.
8185
+ var _a;
8186
+ const pendingUserMessage = (_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.pendingUserMessage;
8187
+ if (pendingUserMessage) {
8188
+ const newSample = { question: pendingUserMessage, answer: content };
8189
+ const newSamples = [...(requirements.samples || []), newSample];
8190
+ const newMetadata = { ...requirements.metadata };
8191
+ delete newMetadata.pendingUserMessage;
8192
+ return {
8193
+ ...requirements,
8194
+ samples: newSamples,
8195
+ metadata: newMetadata,
8196
+ };
8197
+ }
8198
+ return requirements;
8199
+ }
8200
+ }
8201
+
8103
8202
  /**
8104
8203
  * INITIAL MESSAGE commitment definition
8105
8204
  *
@@ -8264,6 +8363,67 @@
8264
8363
  * Note: [💞] Ignore a discrepancy between file name and entity name
8265
8364
  */
8266
8365
 
8366
+ /**
8367
+ * USER MESSAGE commitment definition
8368
+ *
8369
+ * The USER MESSAGE commitment defines a message from the user in the conversation history.
8370
+ * It is used to pre-fill the chat with a conversation history or to provide few-shot examples.
8371
+ *
8372
+ * Example usage in agent source:
8373
+ *
8374
+ * ```book
8375
+ * USER MESSAGE Hello, I have a problem.
8376
+ * ```
8377
+ *
8378
+ * @private [🪔] Maybe export the commitments through some package
8379
+ */
8380
+ class UserMessageCommitmentDefinition extends BaseCommitmentDefinition {
8381
+ constructor() {
8382
+ super('USER MESSAGE');
8383
+ }
8384
+ /**
8385
+ * Short one-line description of USER MESSAGE.
8386
+ */
8387
+ get description() {
8388
+ return 'Defines a **message from the user** in the conversation history.';
8389
+ }
8390
+ /**
8391
+ * Markdown documentation for USER MESSAGE commitment.
8392
+ */
8393
+ get documentation() {
8394
+ return spaceTrim$1.spaceTrim(`
8395
+ # ${this.type}
8396
+
8397
+ Defines a message from the user in the conversation history. This is used to pre-fill the chat with a conversation history or to provide few-shot examples.
8398
+
8399
+ ## Key aspects
8400
+
8401
+ - Represents a message sent by the user.
8402
+ - Used for setting up conversation context.
8403
+ - Can be used in conjunction with AGENT MESSAGE.
8404
+
8405
+ ## Examples
8406
+
8407
+ \`\`\`book
8408
+ Conversation History
8409
+
8410
+ USER MESSAGE Hello, I have a problem.
8411
+ AGENT MESSAGE What seems to be the issue?
8412
+ USER MESSAGE My computer is not starting.
8413
+ \`\`\`
8414
+ `);
8415
+ }
8416
+ applyToAgentModelRequirements(requirements, content) {
8417
+ return {
8418
+ ...requirements,
8419
+ metadata: {
8420
+ ...requirements.metadata,
8421
+ pendingUserMessage: content,
8422
+ },
8423
+ };
8424
+ }
8425
+ }
8426
+
8267
8427
  /**
8268
8428
  * META commitment definition
8269
8429
  *
@@ -8401,6 +8561,165 @@
8401
8561
  * Note: [💞] Ignore a discrepancy between file name and entity name
8402
8562
  */
8403
8563
 
8564
+ /**
8565
+ * META COLOR commitment definition
8566
+ *
8567
+ * The META COLOR commitment sets the agent's accent color.
8568
+ * This commitment is special because it doesn't affect the system message,
8569
+ * but is handled separately in the parsing logic.
8570
+ *
8571
+ * Example usage in agent source:
8572
+ *
8573
+ * ```book
8574
+ * META COLOR #ff0000
8575
+ * META COLOR #00ff00
8576
+ * ```
8577
+ *
8578
+ * @private [🪔] Maybe export the commitments through some package
8579
+ */
8580
+ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
8581
+ constructor() {
8582
+ super('META COLOR', ['COLOR']);
8583
+ }
8584
+ /**
8585
+ * Short one-line description of META COLOR.
8586
+ */
8587
+ get description() {
8588
+ return "Set the agent's accent color.";
8589
+ }
8590
+ /**
8591
+ * Markdown documentation for META COLOR commitment.
8592
+ */
8593
+ get documentation() {
8594
+ return spaceTrim$1.spaceTrim(`
8595
+ # META COLOR
8596
+
8597
+ Sets the agent's accent color.
8598
+
8599
+ ## Key aspects
8600
+
8601
+ - Does not modify the agent's behavior or responses.
8602
+ - Only one \`META COLOR\` should be used per agent.
8603
+ - If multiple are specified, the last one takes precedence.
8604
+ - Used for visual representation in user interfaces.
8605
+
8606
+ ## Examples
8607
+
8608
+ \`\`\`book
8609
+ Professional Assistant
8610
+
8611
+ META COLOR #3498db
8612
+ PERSONA You are a professional business assistant
8613
+ \`\`\`
8614
+
8615
+ \`\`\`book
8616
+ Creative Helper
8617
+
8618
+ META COLOR #e74c3c
8619
+ PERSONA You are a creative and inspiring assistant
8620
+ \`\`\`
8621
+ `);
8622
+ }
8623
+ applyToAgentModelRequirements(requirements, content) {
8624
+ // META COLOR doesn't modify the system message or model requirements
8625
+ // It's handled separately in the parsing logic for profile color extraction
8626
+ // This method exists for consistency with the CommitmentDefinition interface
8627
+ return requirements;
8628
+ }
8629
+ /**
8630
+ * Extracts the profile color from the content
8631
+ * This is used by the parsing logic
8632
+ */
8633
+ extractProfileColor(content) {
8634
+ const trimmedContent = content.trim();
8635
+ return trimmedContent || null;
8636
+ }
8637
+ }
8638
+ /**
8639
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8640
+ */
8641
+
8642
+ /**
8643
+ * META IMAGE commitment definition
8644
+ *
8645
+ * The META IMAGE commitment sets the agent's avatar/profile image URL.
8646
+ * This commitment is special because it doesn't affect the system message,
8647
+ * but is handled separately in the parsing logic.
8648
+ *
8649
+ * Example usage in agent source:
8650
+ *
8651
+ * ```book
8652
+ * META IMAGE https://example.com/avatar.jpg
8653
+ * META IMAGE /assets/agent-avatar.png
8654
+ * ```
8655
+ *
8656
+ * @private [🪔] Maybe export the commitments through some package
8657
+ */
8658
+ class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
8659
+ constructor() {
8660
+ super('META IMAGE', ['IMAGE']);
8661
+ }
8662
+ /**
8663
+ * Short one-line description of META IMAGE.
8664
+ */
8665
+ get description() {
8666
+ return "Set the agent's profile image URL.";
8667
+ }
8668
+ /**
8669
+ * Markdown documentation for META IMAGE commitment.
8670
+ */
8671
+ get documentation() {
8672
+ return spaceTrim$1.spaceTrim(`
8673
+ # META IMAGE
8674
+
8675
+ Sets the agent's avatar/profile image URL.
8676
+
8677
+ ## Key aspects
8678
+
8679
+ - Does not modify the agent's behavior or responses.
8680
+ - Only one \`META IMAGE\` should be used per agent.
8681
+ - If multiple are specified, the last one takes precedence.
8682
+ - Used for visual representation in user interfaces.
8683
+
8684
+ ## Examples
8685
+
8686
+ \`\`\`book
8687
+ Professional Assistant
8688
+
8689
+ META IMAGE https://example.com/professional-avatar.jpg
8690
+ PERSONA You are a professional business assistant
8691
+ STYLE Maintain a formal and courteous tone
8692
+ \`\`\`
8693
+
8694
+ \`\`\`book
8695
+ Creative Helper
8696
+
8697
+ META IMAGE /assets/creative-bot-avatar.png
8698
+ PERSONA You are a creative and inspiring assistant
8699
+ STYLE Be enthusiastic and encouraging
8700
+ ACTION Can help with brainstorming and ideation
8701
+ \`\`\`
8702
+ `);
8703
+ }
8704
+ applyToAgentModelRequirements(requirements, content) {
8705
+ // META IMAGE doesn't modify the system message or model requirements
8706
+ // It's handled separately in the parsing logic for profile image extraction
8707
+ // This method exists for consistency with the CommitmentDefinition interface
8708
+ return requirements;
8709
+ }
8710
+ /**
8711
+ * Extracts the profile image URL from the content
8712
+ * This is used by the parsing logic
8713
+ */
8714
+ extractProfileImageUrl(content) {
8715
+ const trimmedContent = content.trim();
8716
+ return trimmedContent || null;
8717
+ }
8718
+ }
8719
+ /**
8720
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8721
+ */
8722
+
8404
8723
  /**
8405
8724
  * MODEL commitment definition
8406
8725
  *
@@ -9308,6 +9627,8 @@
9308
9627
  new ModelCommitmentDefinition('MODELS'),
9309
9628
  new ActionCommitmentDefinition('ACTION'),
9310
9629
  new ActionCommitmentDefinition('ACTIONS'),
9630
+ new MetaImageCommitmentDefinition(),
9631
+ new MetaColorCommitmentDefinition(),
9311
9632
  new MetaCommitmentDefinition(),
9312
9633
  new NoteCommitmentDefinition('NOTE'),
9313
9634
  new NoteCommitmentDefinition('NOTES'),
@@ -9316,6 +9637,8 @@
9316
9637
  new GoalCommitmentDefinition('GOAL'),
9317
9638
  new GoalCommitmentDefinition('GOALS'),
9318
9639
  new InitialMessageCommitmentDefinition(),
9640
+ new UserMessageCommitmentDefinition(),
9641
+ new AgentMessageCommitmentDefinition(),
9319
9642
  new MessageCommitmentDefinition('MESSAGE'),
9320
9643
  new MessageCommitmentDefinition('MESSAGES'),
9321
9644
  new ScenarioCommitmentDefinition('SCENARIO'),
@@ -9370,6 +9693,45 @@
9370
9693
  function isCommitmentSupported(type) {
9371
9694
  return COMMITMENT_REGISTRY.some((commitmentDefinition) => commitmentDefinition.type === type);
9372
9695
  }
9696
+ /**
9697
+ * Gets all commitment definitions grouped by their aliases
9698
+ *
9699
+ * @returns Array of grouped commitment definitions
9700
+ *
9701
+ * @public exported from `@promptbook/core`
9702
+ */
9703
+ function getGroupedCommitmentDefinitions() {
9704
+ const groupedCommitments = [];
9705
+ for (const commitment of COMMITMENT_REGISTRY) {
9706
+ const lastGroup = groupedCommitments[groupedCommitments.length - 1];
9707
+ // Check if we should group with the previous item
9708
+ let shouldGroup = false;
9709
+ if (lastGroup) {
9710
+ const lastPrimary = lastGroup.primary;
9711
+ // Case 1: Same class constructor (except NotYetImplemented)
9712
+ if (!(commitment instanceof NotYetImplementedCommitmentDefinition) &&
9713
+ commitment.constructor === lastPrimary.constructor) {
9714
+ shouldGroup = true;
9715
+ }
9716
+ // Case 2: NotYetImplemented with prefix matching (e.g. BEHAVIOUR -> BEHAVIOURS)
9717
+ else if (commitment instanceof NotYetImplementedCommitmentDefinition &&
9718
+ lastPrimary instanceof NotYetImplementedCommitmentDefinition &&
9719
+ commitment.type.startsWith(lastPrimary.type)) {
9720
+ shouldGroup = true;
9721
+ }
9722
+ }
9723
+ if (shouldGroup && lastGroup) {
9724
+ lastGroup.aliases.push(commitment.type);
9725
+ }
9726
+ else {
9727
+ groupedCommitments.push({
9728
+ primary: commitment,
9729
+ aliases: [],
9730
+ });
9731
+ }
9732
+ }
9733
+ return $deepFreeze(groupedCommitments);
9734
+ }
9373
9735
  /**
9374
9736
  * TODO: [🧠] Maybe create through standardized $register
9375
9737
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -10109,6 +10471,18 @@
10109
10471
  * TODO: [🧠][🌻] Maybe export through `@promptbook/markdown-utils` not `@promptbook/utils`
10110
10472
  */
10111
10473
 
10474
+ /**
10475
+ * Normalizes message text for comparison
10476
+ *
10477
+ * @param text The message text to normalize
10478
+ * @returns The normalized message text
10479
+ *
10480
+ * @public exported from `@promptbook/utils`
10481
+ */
10482
+ function normalizeMessageText(text) {
10483
+ return spaceTrim$1.spaceTrim(text);
10484
+ }
10485
+
10112
10486
  /**
10113
10487
  * Removes quotes from a string
10114
10488
  *
@@ -10221,6 +10595,14 @@
10221
10595
  links.push(spaceTrim__default["default"](commitment.content));
10222
10596
  continue;
10223
10597
  }
10598
+ if (commitment.type === 'META IMAGE') {
10599
+ meta.image = spaceTrim__default["default"](commitment.content);
10600
+ continue;
10601
+ }
10602
+ if (commitment.type === 'META COLOR') {
10603
+ meta.color = spaceTrim__default["default"](commitment.content);
10604
+ continue;
10605
+ }
10224
10606
  if (commitment.type !== 'META') {
10225
10607
  continue;
10226
10608
  }
@@ -10236,6 +10618,10 @@
10236
10618
  if (!meta.image) {
10237
10619
  meta.image = generatePlaceholderAgentProfileImageUrl(parseResult.agentName || '!!');
10238
10620
  }
10621
+ // Generate fullname fallback if no meta fullname specified
10622
+ if (!meta.fullname) {
10623
+ meta.fullname = parseResult.agentName || createDefaultAgentName(agentSource);
10624
+ }
10239
10625
  // Parse parameters using unified approach - both @Parameter and {parameter} notations
10240
10626
  // are treated as the same syntax feature with unified representation
10241
10627
  const parameters = parseParameters(agentSource);
@@ -10601,7 +10987,96 @@
10601
10987
  * Deletes an agent from the collection
10602
10988
  */
10603
10989
  async deleteAgent(agentName) {
10604
- throw new NotYetImplementedError('Method not implemented.');
10990
+ const deleteResult = await this.supabaseClient
10991
+ .from(this.getTableName('Agent'))
10992
+ .delete()
10993
+ .eq('agentName', agentName);
10994
+ if (deleteResult.error) {
10995
+ throw new DatabaseError(spaceTrim((block) => `
10996
+ Error deleting agent "${agentName}" from Supabase:
10997
+
10998
+ ${block(deleteResult.error.message)}
10999
+ `));
11000
+ }
11001
+ }
11002
+ /**
11003
+ * List history of an agent
11004
+ */
11005
+ async listAgentHistory(agentName) {
11006
+ const result = await this.supabaseClient
11007
+ .from(this.getTableName('AgentHistory'))
11008
+ .select('id, createdAt, agentHash, promptbookEngineVersion')
11009
+ .eq('agentName', agentName)
11010
+ .order('createdAt', { ascending: false });
11011
+ if (result.error) {
11012
+ throw new DatabaseError(spaceTrim((block) => `
11013
+ Error listing history for agent "${agentName}" from Supabase:
11014
+
11015
+ ${block(result.error.message)}
11016
+ `));
11017
+ }
11018
+ return result.data;
11019
+ }
11020
+ /**
11021
+ * List agents that are in history but not in the active agents list
11022
+ */
11023
+ async listDeletedAgents() {
11024
+ const historyNamesResult = await this.supabaseClient.from(this.getTableName('AgentHistory')).select('agentName');
11025
+ const currentNamesResult = await this.supabaseClient.from(this.getTableName('Agent')).select('agentName');
11026
+ if (historyNamesResult.error) {
11027
+ throw new DatabaseError(spaceTrim((block) => `
11028
+ Error fetching agent history names from Supabase:
11029
+
11030
+ ${block(historyNamesResult.error.message)}
11031
+ `));
11032
+ }
11033
+ if (currentNamesResult.error) {
11034
+ throw new DatabaseError(spaceTrim((block) => `
11035
+ Error fetching current agent names from Supabase:
11036
+
11037
+ ${block(currentNamesResult.error.message)}
11038
+ `));
11039
+ }
11040
+ const currentNames = new Set(currentNamesResult.data.map((d) => d.agentName));
11041
+ const deletedNames = new Set();
11042
+ for (const { agentName } of historyNamesResult.data) {
11043
+ if (!currentNames.has(agentName)) {
11044
+ deletedNames.add(agentName);
11045
+ }
11046
+ }
11047
+ return Array.from(deletedNames);
11048
+ }
11049
+ /**
11050
+ * Restore an agent from history
11051
+ */
11052
+ async restoreAgent(historyId) {
11053
+ const historyResult = await this.supabaseClient
11054
+ .from(this.getTableName('AgentHistory'))
11055
+ .select('*')
11056
+ .eq('id', historyId)
11057
+ .single();
11058
+ if (historyResult.error) {
11059
+ throw new DatabaseError(spaceTrim((block) => `
11060
+ Error fetching agent history item "${historyId}" from Supabase:
11061
+
11062
+ ${block(historyResult.error.message)}
11063
+ `));
11064
+ }
11065
+ const { agentName, agentSource } = historyResult.data;
11066
+ // Check if agent exists
11067
+ const agentResult = await this.supabaseClient
11068
+ .from(this.getTableName('Agent'))
11069
+ .select('id')
11070
+ .eq('agentName', agentName)
11071
+ .single();
11072
+ if (agentResult.data) {
11073
+ // Update
11074
+ await this.updateAgentSource(agentName, agentSource);
11075
+ }
11076
+ else {
11077
+ // Insert (Restore from deleted)
11078
+ await this.createAgent(agentSource);
11079
+ }
10605
11080
  }
10606
11081
  /**
10607
11082
  * Get the Supabase table name with prefix
@@ -17030,12 +17505,15 @@
17030
17505
  fileStreams.push(file);
17031
17506
  }
17032
17507
  else {
17508
+ /*
17509
+ TODO: [🐱‍🚀] Resolve problem with browser environment
17033
17510
  // Assume it's a local file path
17034
17511
  // Note: This will work in Node.js environment
17035
17512
  // For browser environments, this would need different handling
17036
17513
  const fs = await import('fs');
17037
17514
  const fileStream = fs.createReadStream(source);
17038
17515
  fileStreams.push(fileStream);
17516
+ */
17039
17517
  }
17040
17518
  }
17041
17519
  catch (error) {
@@ -17124,12 +17602,15 @@
17124
17602
  fileStreams.push(file);
17125
17603
  }
17126
17604
  else {
17605
+ /*
17606
+ TODO: [🐱‍🚀] Resolve problem with browser environment
17127
17607
  // Assume it's a local file path
17128
17608
  // Note: This will work in Node.js environment
17129
17609
  // For browser environments, this would need different handling
17130
17610
  const fs = await import('fs');
17131
17611
  const fileStream = fs.createReadStream(source);
17132
17612
  fileStreams.push(fileStream);
17613
+ */
17133
17614
  }
17134
17615
  }
17135
17616
  catch (error) {
@@ -17265,7 +17746,7 @@
17265
17746
  }
17266
17747
  get title() {
17267
17748
  const agentInfo = this.getAgentInfo();
17268
- return (agentInfo.agentName || 'Agent');
17749
+ return (agentInfo.meta.fullname || agentInfo.agentName || 'Agent');
17269
17750
  }
17270
17751
  get description() {
17271
17752
  const agentInfo = this.getAgentInfo();
@@ -17278,7 +17759,7 @@
17278
17759
  }
17279
17760
  return {
17280
17761
  name: agentInfo.agentName.toUpperCase().replace(/\s+/g, '_'),
17281
- fullname: agentInfo.agentName,
17762
+ fullname: agentInfo.meta.fullname || agentInfo.agentName,
17282
17763
  color: agentInfo.meta.color || '#6366f1',
17283
17764
  avatarSrc: agentInfo.meta.image,
17284
17765
  };
@@ -17503,19 +17984,63 @@
17503
17984
  * Note: This method also implements the learning mechanism
17504
17985
  */
17505
17986
  async callChatModelStream(prompt, onProgress) {
17987
+ // [1] Check if the user is asking the same thing as in the samples
17988
+ const modelRequirements = await this.getAgentModelRequirements();
17989
+ if (modelRequirements.samples) {
17990
+ const normalizedPrompt = normalizeMessageText(prompt.content);
17991
+ const sample = modelRequirements.samples.find((s) => normalizeMessageText(s.question) === normalizedPrompt);
17992
+ if (sample) {
17993
+ const now = new Date().toISOString();
17994
+ const result = {
17995
+ content: sample.answer,
17996
+ modelName: this.modelName,
17997
+ timing: {
17998
+ start: now,
17999
+ complete: now,
18000
+ },
18001
+ usage: {
18002
+ price: { value: 0, isUncertain: true },
18003
+ input: {
18004
+ tokensCount: { value: 0, isUncertain: true },
18005
+ charactersCount: { value: 0, isUncertain: true },
18006
+ wordsCount: { value: 0, isUncertain: true },
18007
+ linesCount: { value: 0, isUncertain: true },
18008
+ sentencesCount: { value: 0, isUncertain: true },
18009
+ paragraphsCount: { value: 0, isUncertain: true },
18010
+ pagesCount: { value: 0, isUncertain: true },
18011
+ },
18012
+ output: {
18013
+ tokensCount: { value: 0, isUncertain: true },
18014
+ charactersCount: { value: 0, isUncertain: true },
18015
+ wordsCount: { value: 0, isUncertain: true },
18016
+ linesCount: { value: 0, isUncertain: true },
18017
+ sentencesCount: { value: 0, isUncertain: true },
18018
+ paragraphsCount: { value: 0, isUncertain: true },
18019
+ pagesCount: { value: 0, isUncertain: true },
18020
+ },
18021
+ },
18022
+ rawPromptContent: prompt.content,
18023
+ rawRequest: null,
18024
+ rawResponse: { sample },
18025
+ };
18026
+ onProgress(result);
18027
+ return result;
18028
+ }
18029
+ }
17506
18030
  const result = await super.callChatModelStream(prompt, onProgress);
18031
+ if (result.rawResponse && 'sample' in result.rawResponse) {
18032
+ return result;
18033
+ }
17507
18034
  // TODO: !!! Extract learning to separate method
17508
18035
  // Learning: Append the conversation sample to the agent source
17509
18036
  const learningExample = spaceTrim__default["default"]((block) => `
17510
18037
 
17511
18038
  ---
17512
18039
 
17513
- SAMPLE
17514
-
17515
- User:
18040
+ USER MESSAGE
17516
18041
  ${block(prompt.content)}
17517
18042
 
17518
- ${this.title} (Me, the Agent):
18043
+ AGENT MESSAGE
17519
18044
  ${block(result.content)}
17520
18045
 
17521
18046
  `);
@@ -17591,6 +18116,70 @@
17591
18116
  * Note: [💞] Ignore a discrepancy between file name and entity name
17592
18117
  */
17593
18118
 
18119
+ /**
18120
+ * Function `isValidPipelineString` will validate the if the string is a valid pipeline string
18121
+ * It does not check if the string is fully logically correct, but if it is a string that can be a pipeline string or the string looks completely different.
18122
+ *
18123
+ * @param {string} pipelineString the candidate for a pipeline string
18124
+ * @returns {boolean} if the string is a valid pipeline string
18125
+ * @public exported from `@promptbook/core`
18126
+ */
18127
+ function isValidPipelineString(pipelineString) {
18128
+ try {
18129
+ validatePipelineString(pipelineString);
18130
+ return true;
18131
+ }
18132
+ catch (error) {
18133
+ assertsError(error);
18134
+ return false;
18135
+ }
18136
+ }
18137
+ /**
18138
+ * TODO: [🧠][🈴] Where is the best location for this file
18139
+ */
18140
+
18141
+ /**
18142
+ * Tag function for notating a pipeline with a book\`...\ notation as template literal
18143
+ *
18144
+ * Note: There are 3 similar functions:
18145
+ * 1) `prompt` for notating single prompt exported from `@promptbook/utils`
18146
+ * 2) `promptTemplate` alias for `prompt`
18147
+ * 3) `book` for notating and validating entire books exported from `@promptbook/utils`
18148
+ *
18149
+ * @param strings The static string parts of the template literal
18150
+ * @param values The dynamic values embedded within the template literal used as data
18151
+ * @returns the pipeline string
18152
+ * @public exported from `@promptbook/core`
18153
+ */
18154
+ function book(strings, ...values) {
18155
+ const bookString = prompt(strings, ...values);
18156
+ if (!isValidPipelineString(bookString)) {
18157
+ // TODO: Make the CustomError for this
18158
+ throw new Error(spaceTrim__default["default"](`
18159
+ The string is not a valid pipeline string
18160
+
18161
+ book\`
18162
+ ${bookString}
18163
+ \`
18164
+ `));
18165
+ }
18166
+ if (!isValidBook(bookString)) {
18167
+ // TODO: Make the CustomError for this
18168
+ throw new Error(spaceTrim__default["default"](`
18169
+ The string is not a valid book
18170
+
18171
+ book\`
18172
+ ${bookString}
18173
+ \`
18174
+ `));
18175
+ }
18176
+ return padBook(bookString);
18177
+ }
18178
+ /**
18179
+ * TODO: [🧠][🈴] Where is the best location for this file
18180
+ * Note: [💞] Ignore a discrepancy between file name and entity name
18181
+ */
18182
+
17594
18183
  /**
17595
18184
  * Represents one AI Agent
17596
18185
  *
@@ -17612,11 +18201,12 @@
17612
18201
  const profile = await profileResponse.json();
17613
18202
  // Note: We are creating dummy agent source because we don't have the source from the remote agent
17614
18203
  // But we populate the metadata from the profile
17615
- const agentSource = new rxjs.BehaviorSubject(`
17616
- # ${profile.agentName}
18204
+ const agentSource = new rxjs.BehaviorSubject(book `
18205
+ ${profile.agentName}
17617
18206
 
17618
- ${profile.personaDescription}
18207
+ ${profile.personaDescription}
17619
18208
  `);
18209
+ // <- TODO: [🐱‍🚀] createBookFromProfile
17620
18210
  // <- TODO: [🐱‍🚀] Support updating and self-updating
17621
18211
  const remoteAgent = new RemoteAgent({
17622
18212
  ...options,
@@ -17641,10 +18231,12 @@ ${profile.personaDescription}
17641
18231
  remoteAgent.initialMessage = profile.initialMessage;
17642
18232
  remoteAgent.links = profile.links;
17643
18233
  remoteAgent.meta = profile.meta;
18234
+ remoteAgent._isVoiceCallingEnabled = profile.isVoiceCallingEnabled === true; // [✨✷] Store voice calling status
17644
18235
  return remoteAgent;
17645
18236
  }
17646
18237
  constructor(options) {
17647
18238
  super(options);
18239
+ this._isVoiceCallingEnabled = false; // [✨✷] Track voice calling status
17648
18240
  this.agentUrl = options.agentUrl;
17649
18241
  }
17650
18242
  get agentName() {
@@ -17660,8 +18252,49 @@ ${profile.personaDescription}
17660
18252
  return this.callChatModelStream(prompt, () => { });
17661
18253
  }
17662
18254
  /**
17663
- * Calls the agent on agents remote server with streaming
18255
+ * Calls the agent on agents remote server with voice
18256
+ * [✨✷] Only available when voice calling is enabled on the server
18257
+ * Returns undefined if voice calling is disabled
17664
18258
  */
18259
+ get callVoiceChatModel() {
18260
+ if (!this._isVoiceCallingEnabled) {
18261
+ return undefined;
18262
+ }
18263
+ return async (audio, prompt) => {
18264
+ // Ensure we're working with a chat prompt
18265
+ if (prompt.modelRequirements.modelVariant !== 'CHAT') {
18266
+ throw new Error('Agents only supports chat prompts');
18267
+ }
18268
+ const chatPrompt = prompt;
18269
+ const formData = new FormData();
18270
+ formData.append('audio', audio, 'voice.webm');
18271
+ formData.append('message', prompt.content);
18272
+ if (chatPrompt.thread) {
18273
+ formData.append('thread', JSON.stringify(chatPrompt.thread));
18274
+ }
18275
+ const response = await fetch(`${this.agentUrl}/api/voice`, {
18276
+ method: 'POST',
18277
+ body: formData,
18278
+ });
18279
+ if (!response.ok) {
18280
+ throw new Error(`Voice chat failed: ${response.statusText}`);
18281
+ }
18282
+ const result = await response.json();
18283
+ // Convert base64 audio back to Blob
18284
+ const binaryString = atob(result.audio);
18285
+ const bytes = new Uint8Array(binaryString.length);
18286
+ for (let i = 0; i < binaryString.length; i++) {
18287
+ bytes[i] = binaryString.charCodeAt(i);
18288
+ }
18289
+ const audioBlob = new Blob([bytes], { type: 'audio/mp3' });
18290
+ return {
18291
+ text: result.agentMessage || result.text,
18292
+ userMessage: result.userMessage,
18293
+ agentMessage: result.agentMessage || result.text,
18294
+ audio: audioBlob,
18295
+ };
18296
+ };
18297
+ }
17665
18298
  async callChatModelStream(prompt, onProgress) {
17666
18299
  // Ensure we're working with a chat prompt
17667
18300
  if (prompt.modelRequirements.modelVariant !== 'CHAT') {
@@ -18198,70 +18831,6 @@ ${profile.personaDescription}
18198
18831
  return migratedPipeline;
18199
18832
  }
18200
18833
 
18201
- /**
18202
- * Function `isValidPipelineString` will validate the if the string is a valid pipeline string
18203
- * It does not check if the string is fully logically correct, but if it is a string that can be a pipeline string or the string looks completely different.
18204
- *
18205
- * @param {string} pipelineString the candidate for a pipeline string
18206
- * @returns {boolean} if the string is a valid pipeline string
18207
- * @public exported from `@promptbook/core`
18208
- */
18209
- function isValidPipelineString(pipelineString) {
18210
- try {
18211
- validatePipelineString(pipelineString);
18212
- return true;
18213
- }
18214
- catch (error) {
18215
- assertsError(error);
18216
- return false;
18217
- }
18218
- }
18219
- /**
18220
- * TODO: [🧠][🈴] Where is the best location for this file
18221
- */
18222
-
18223
- /**
18224
- * Tag function for notating a pipeline with a book\`...\ notation as template literal
18225
- *
18226
- * Note: There are 3 similar functions:
18227
- * 1) `prompt` for notating single prompt exported from `@promptbook/utils`
18228
- * 2) `promptTemplate` alias for `prompt`
18229
- * 3) `book` for notating and validating entire books exported from `@promptbook/utils`
18230
- *
18231
- * @param strings The static string parts of the template literal
18232
- * @param values The dynamic values embedded within the template literal used as data
18233
- * @returns the pipeline string
18234
- * @public exported from `@promptbook/core`
18235
- */
18236
- function book(strings, ...values) {
18237
- const bookString = prompt(strings, ...values);
18238
- if (!isValidPipelineString(bookString)) {
18239
- // TODO: Make the CustomError for this
18240
- throw new Error(spaceTrim__default["default"](`
18241
- The string is not a valid pipeline string
18242
-
18243
- book\`
18244
- ${bookString}
18245
- \`
18246
- `));
18247
- }
18248
- if (!isValidBook(bookString)) {
18249
- // TODO: Make the CustomError for this
18250
- throw new Error(spaceTrim__default["default"](`
18251
- The string is not a valid book
18252
-
18253
- book\`
18254
- ${bookString}
18255
- \`
18256
- `));
18257
- }
18258
- return padBook(bookString);
18259
- }
18260
- /**
18261
- * TODO: [🧠][🈴] Where is the best location for this file
18262
- * Note: [💞] Ignore a discrepancy between file name and entity name
18263
- */
18264
-
18265
18834
  /**
18266
18835
  * Convert identification to Promptbook token
18267
18836
  *
@@ -19024,7 +19593,7 @@ ${profile.personaDescription}
19024
19593
  const agentSource = validateBook(spaceTrim__default["default"]((block) => `
19025
19594
  ${agentName}
19026
19595
 
19027
- META COLOR ${color || '#3498db' /* <- TODO: [🧠] [🐱‍🚀] Best default color */}
19596
+ META COLOR ${color || PROMPTBOOK_COLOR.toHex()}
19028
19597
  PERSONA ${block(personaDescription)}
19029
19598
  `));
19030
19599
  return agentSource;
@@ -19042,6 +19611,7 @@ ${profile.personaDescription}
19042
19611
  exports.ADMIN_EMAIL = ADMIN_EMAIL;
19043
19612
  exports.ADMIN_GITHUB_NAME = ADMIN_GITHUB_NAME;
19044
19613
  exports.API_REQUEST_TIMEOUT = API_REQUEST_TIMEOUT;
19614
+ exports.AUTO_FEDERATED_AGENT_SERVER_URLS = AUTO_FEDERATED_AGENT_SERVER_URLS;
19045
19615
  exports.AbstractFormatError = AbstractFormatError;
19046
19616
  exports.Agent = Agent;
19047
19617
  exports.AgentCollectionInSupabase = AgentCollectionInSupabase;
@@ -19190,6 +19760,7 @@ ${profile.personaDescription}
19190
19760
  exports.getAllCommitmentDefinitions = getAllCommitmentDefinitions;
19191
19761
  exports.getAllCommitmentTypes = getAllCommitmentTypes;
19192
19762
  exports.getCommitmentDefinition = getCommitmentDefinition;
19763
+ exports.getGroupedCommitmentDefinitions = getGroupedCommitmentDefinitions;
19193
19764
  exports.getPipelineInterface = getPipelineInterface;
19194
19765
  exports.getSingleLlmExecutionTools = getSingleLlmExecutionTools;
19195
19766
  exports.identificationToPromptbookToken = identificationToPromptbookToken;