@promptbook/core 0.104.0-1 → 0.104.0-3

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 (31) hide show
  1. package/esm/index.es.js +335 -89
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/types.index.d.ts +8 -2
  4. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +6 -1
  5. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
  6. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  7. package/esm/typings/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +13 -0
  8. package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
  9. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +7 -11
  10. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +2 -2
  11. package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
  12. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +13 -7
  13. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +6 -0
  14. package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
  15. package/esm/typings/src/commitments/index.d.ts +2 -1
  16. package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
  17. package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
  18. package/esm/typings/src/types/Message.d.ts +49 -0
  19. package/esm/typings/src/types/typeAliases.d.ts +12 -0
  20. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
  21. package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
  22. package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
  23. package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
  24. package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
  25. package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
  26. package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
  27. package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
  28. package/esm/typings/src/version.d.ts +1 -1
  29. package/package.json +1 -1
  30. package/umd/index.umd.js +341 -95
  31. package/umd/index.umd.js.map +1 -1
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-1';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.104.0-3';
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
@@ -7965,6 +7965,114 @@
7965
7965
  * Note: [💞] Ignore a discrepancy between file name and entity name
7966
7966
  */
7967
7967
 
7968
+ /**
7969
+ * DICTIONARY commitment definition
7970
+ *
7971
+ * The DICTIONARY commitment defines specific terms and their meanings that the agent should use correctly
7972
+ * in its reasoning and responses. This ensures consistent terminology usage.
7973
+ *
7974
+ * Key features:
7975
+ * - Multiple DICTIONARY commitments are automatically merged into one
7976
+ * - Content is placed in a dedicated section of the system message
7977
+ * - Terms and definitions are stored in metadata.DICTIONARY for debugging
7978
+ * - Agent should use the defined terms correctly in responses
7979
+ *
7980
+ * Example usage in agent source:
7981
+ *
7982
+ * ```book
7983
+ * Legal Assistant
7984
+ *
7985
+ * PERSONA You are a knowledgeable legal assistant
7986
+ * DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
7987
+ * DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
7988
+ * DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
7989
+ * ```
7990
+ *
7991
+ * @private [🪔] Maybe export the commitments through some package
7992
+ */
7993
+ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
7994
+ constructor() {
7995
+ super('DICTIONARY');
7996
+ }
7997
+ /**
7998
+ * Short one-line description of DICTIONARY.
7999
+ */
8000
+ get description() {
8001
+ return 'Define terms and their meanings for consistent terminology usage.';
8002
+ }
8003
+ /**
8004
+ * Icon for this commitment.
8005
+ */
8006
+ get icon() {
8007
+ return '📚';
8008
+ }
8009
+ /**
8010
+ * Markdown documentation for DICTIONARY commitment.
8011
+ */
8012
+ get documentation() {
8013
+ return spaceTrim$1.spaceTrim(`
8014
+ # DICTIONARY
8015
+
8016
+ Defines specific terms and their meanings that the agent should use correctly in reasoning and responses.
8017
+
8018
+ ## Key aspects
8019
+
8020
+ - Multiple \`DICTIONARY\` commitments are merged together.
8021
+ - Terms are defined in the format: "Term is definition"
8022
+ - The agent should use these terms consistently in responses.
8023
+ - Definitions help ensure accurate and consistent terminology.
8024
+
8025
+ ## Examples
8026
+
8027
+ \`\`\`book
8028
+ Legal Assistant
8029
+
8030
+ PERSONA You are a knowledgeable legal assistant specializing in criminal law
8031
+ DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
8032
+ DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
8033
+ DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
8034
+ \`\`\`
8035
+
8036
+ \`\`\`book
8037
+ Medical Assistant
8038
+
8039
+ PERSONA You are a helpful medical assistant
8040
+ DICTIONARY Hypertension is persistently high blood pressure
8041
+ DICTIONARY Diabetes is a chronic condition that affects how the body processes blood sugar
8042
+ DICTIONARY Vaccine is a biological preparation that provides active immunity to a particular disease
8043
+ \`\`\`
8044
+ `);
8045
+ }
8046
+ applyToAgentModelRequirements(requirements, content) {
8047
+ var _a;
8048
+ const trimmedContent = content.trim();
8049
+ if (!trimmedContent) {
8050
+ return requirements;
8051
+ }
8052
+ // Get existing dictionary entries from metadata
8053
+ const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
8054
+ // Merge the new dictionary entry with existing entries
8055
+ const mergedDictionary = existingDictionary
8056
+ ? `${existingDictionary}\n${trimmedContent}`
8057
+ : trimmedContent;
8058
+ // Store the merged dictionary in metadata for debugging and inspection
8059
+ const updatedMetadata = {
8060
+ ...requirements.metadata,
8061
+ DICTIONARY: mergedDictionary,
8062
+ };
8063
+ // Create the dictionary section for the system message
8064
+ // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
8065
+ const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
8066
+ return {
8067
+ ...this.appendToSystemMessage(requirements, dictionarySection),
8068
+ metadata: updatedMetadata,
8069
+ };
8070
+ }
8071
+ }
8072
+ /**
8073
+ * Note: [💞] Ignore a discrepancy between file name and entity name
8074
+ */
8075
+
7968
8076
  /**
7969
8077
  * FORMAT commitment definition
7970
8078
  *
@@ -10785,6 +10893,7 @@
10785
10893
  new DeleteCommitmentDefinition('CANCEL'),
10786
10894
  new DeleteCommitmentDefinition('DISCARD'),
10787
10895
  new DeleteCommitmentDefinition('REMOVE'),
10896
+ new DictionaryCommitmentDefinition(),
10788
10897
  new OpenCommitmentDefinition(),
10789
10898
  new ClosedCommitmentDefinition(),
10790
10899
  new UseBrowserCommitmentDefinition(),
@@ -10936,17 +11045,64 @@
10936
11045
  };
10937
11046
  }
10938
11047
  const lines = agentSource.split('\n');
10939
- const agentName = (((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.trim()) || null);
11048
+ let agentName = null;
11049
+ let agentNameLineIndex = -1;
11050
+ // Find the agent name: first non-empty line that is not a commitment and not a horizontal line
11051
+ for (let i = 0; i < lines.length; i++) {
11052
+ const line = lines[i];
11053
+ if (line === undefined) {
11054
+ continue;
11055
+ }
11056
+ const trimmed = line.trim();
11057
+ if (!trimmed) {
11058
+ continue;
11059
+ }
11060
+ const isHorizontal = HORIZONTAL_LINE_PATTERN.test(line);
11061
+ if (isHorizontal) {
11062
+ continue;
11063
+ }
11064
+ let isCommitment = false;
11065
+ for (const definition of COMMITMENT_REGISTRY) {
11066
+ const typeRegex = definition.createTypeRegex();
11067
+ const match = typeRegex.exec(trimmed);
11068
+ if (match && ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.type)) {
11069
+ isCommitment = true;
11070
+ break;
11071
+ }
11072
+ }
11073
+ if (!isCommitment) {
11074
+ agentName = trimmed;
11075
+ agentNameLineIndex = i;
11076
+ break;
11077
+ }
11078
+ }
10940
11079
  const commitments = [];
10941
11080
  const nonCommitmentLines = [];
10942
- // Always add the first line (agent name) to non-commitment lines
10943
- if (lines[0] !== undefined) {
10944
- nonCommitmentLines.push(lines[0]);
11081
+ // Add lines before agentName that are horizontal lines (they are non-commitment)
11082
+ for (let i = 0; i < agentNameLineIndex; i++) {
11083
+ const line = lines[i];
11084
+ if (line === undefined) {
11085
+ continue;
11086
+ }
11087
+ const trimmed = line.trim();
11088
+ if (!trimmed) {
11089
+ continue;
11090
+ }
11091
+ const isHorizontal = HORIZONTAL_LINE_PATTERN.test(line);
11092
+ if (isHorizontal) {
11093
+ nonCommitmentLines.push(line);
11094
+ }
11095
+ // Note: Commitments before agentName are not added to nonCommitmentLines
11096
+ }
11097
+ // Add the agent name line to non-commitment lines
11098
+ if (agentNameLineIndex >= 0) {
11099
+ nonCommitmentLines.push(lines[agentNameLineIndex]);
10945
11100
  }
10946
11101
  // Parse commitments with multiline support
10947
11102
  let currentCommitment = null;
10948
- // Process lines starting from the second line (skip agent name)
10949
- for (let i = 1; i < lines.length; i++) {
11103
+ // Process lines starting from after the agent name line
11104
+ const startIndex = agentNameLineIndex >= 0 ? agentNameLineIndex + 1 : 0;
11105
+ for (let i = startIndex; i < lines.length; i++) {
10950
11106
  const line = lines[i];
10951
11107
  if (line === undefined) {
10952
11108
  continue;
@@ -11469,13 +11625,14 @@
11469
11625
  *
11470
11626
  * @public exported from `@promptbook/utils`
11471
11627
  */
11472
- const $isRunningInBrowser = new Function(`
11473
- try {
11474
- return this === window;
11475
- } catch (e) {
11476
- return false;
11628
+ function $isRunningInBrowser() {
11629
+ try {
11630
+ return typeof window !== 'undefined' && typeof window.document !== 'undefined';
11631
+ }
11632
+ catch (e) {
11633
+ return false;
11634
+ }
11477
11635
  }
11478
- `);
11479
11636
  /**
11480
11637
  * TODO: [🎺]
11481
11638
  */
@@ -11487,13 +11644,15 @@
11487
11644
  *
11488
11645
  * @public exported from `@promptbook/utils`
11489
11646
  */
11490
- const $isRunningInJest = new Function(`
11491
- try {
11492
- return process.env.JEST_WORKER_ID !== undefined;
11493
- } catch (e) {
11494
- return false;
11647
+ function $isRunningInJest() {
11648
+ var _a;
11649
+ try {
11650
+ return typeof process !== 'undefined' && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.JEST_WORKER_ID) !== undefined;
11651
+ }
11652
+ catch (e) {
11653
+ return false;
11654
+ }
11495
11655
  }
11496
- `);
11497
11656
  /**
11498
11657
  * TODO: [🎺]
11499
11658
  */
@@ -11505,13 +11664,14 @@
11505
11664
  *
11506
11665
  * @public exported from `@promptbook/utils`
11507
11666
  */
11508
- const $isRunningInNode = new Function(`
11509
- try {
11510
- return this === global;
11511
- } catch (e) {
11512
- return false;
11667
+ function $isRunningInNode() {
11668
+ try {
11669
+ return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
11670
+ }
11671
+ catch (e) {
11672
+ return false;
11673
+ }
11513
11674
  }
11514
- `);
11515
11675
  /**
11516
11676
  * TODO: [🎺]
11517
11677
  */
@@ -11523,17 +11683,17 @@
11523
11683
  *
11524
11684
  * @public exported from `@promptbook/utils`
11525
11685
  */
11526
- const $isRunningInWebWorker = new Function(`
11527
- try {
11528
- if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
11529
- return true;
11530
- } else {
11686
+ function $isRunningInWebWorker() {
11687
+ try {
11688
+ // Note: Check for importScripts which is specific to workers
11689
+ // and not available in the main browser thread
11690
+ return (typeof self !== 'undefined' &&
11691
+ typeof self.importScripts === 'function');
11692
+ }
11693
+ catch (e) {
11531
11694
  return false;
11532
11695
  }
11533
- } catch (e) {
11534
- return false;
11535
11696
  }
11536
- `);
11537
11697
  /**
11538
11698
  * TODO: [🎺]
11539
11699
  */
@@ -11791,6 +11951,7 @@
11791
11951
  return {
11792
11952
  agentName: normalizeAgentName(parseResult.agentName || createDefaultAgentName(agentSource)),
11793
11953
  agentHash,
11954
+ permanentId: meta.id,
11794
11955
  personaDescription,
11795
11956
  initialMessage,
11796
11957
  meta,
@@ -11982,6 +12143,41 @@
11982
12143
  // <- [🐱‍🚀] Buttons into genesis book
11983
12144
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
11984
12145
 
12146
+ /**
12147
+ * Base58 characters
12148
+ */
12149
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
12150
+ /**
12151
+ * Generates random base58 string
12152
+ *
12153
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
12154
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
12155
+ *
12156
+ * @param length - length of the string
12157
+ * @returns secure random base58 string
12158
+ *
12159
+ * @private internal helper function
12160
+ */
12161
+ function $randomBase58(length) {
12162
+ let result = '';
12163
+ while (result.length < length) {
12164
+ // Generate enough bytes to cover the remaining length, plus some extra buffer to reduce calls
12165
+ // But simply generating `length - result.length` is fine for small lengths
12166
+ const bytes = crypto.randomBytes(length - result.length);
12167
+ for (let i = 0; i < bytes.length; i++) {
12168
+ const byte = bytes[i];
12169
+ // 58 * 4 = 232
12170
+ // We discard values >= 232 to avoid modulo bias
12171
+ if (byte < 232) {
12172
+ result += BASE58_ALPHABET[byte % 58];
12173
+ if (result.length === length)
12174
+ break;
12175
+ }
12176
+ }
12177
+ }
12178
+ return result;
12179
+ }
12180
+
11985
12181
  // import { getTableName } from '../../../../../apps/agents-server/src/database/getTableName';
11986
12182
  // <- TODO: [🐱‍🚀] Prevent imports from `/apps` -> `/src`
11987
12183
  /**
@@ -12015,19 +12211,20 @@
12015
12211
  const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
12016
12212
  const selectResult = await this.supabaseClient
12017
12213
  .from(this.getTableName('Agent'))
12018
- .select('agentName,agentProfile');
12214
+ .select('agentName,agentProfile,permanentId')
12215
+ .is('deletedAt', null);
12019
12216
  if (selectResult.error) {
12020
12217
  throw new DatabaseError(spaceTrim((block) => `
12021
-
12218
+
12022
12219
  Error fetching agents from Supabase:
12023
-
12220
+
12024
12221
  ${block(selectResult.error.message)}
12025
12222
  `));
12026
12223
  }
12027
12224
  if (isVerbose) {
12028
12225
  console.info(`Found ${selectResult.data.length} agents in directory`);
12029
12226
  }
12030
- return selectResult.data.map(({ agentName, agentProfile }) => {
12227
+ return selectResult.data.map(({ agentName, agentProfile, permanentId }) => {
12031
12228
  if (isVerbose && agentProfile.agentName !== agentName) {
12032
12229
  console.warn(spaceTrim(`
12033
12230
  Agent name mismatch for agent "${agentName}". Using name from database.
@@ -12039,6 +12236,7 @@
12039
12236
  return {
12040
12237
  ...agentProfile,
12041
12238
  agentName,
12239
+ permanentId: permanentId || agentProfile.permanentId,
12042
12240
  };
12043
12241
  });
12044
12242
  }
@@ -12049,7 +12247,7 @@
12049
12247
  const selectResult = await this.supabaseClient
12050
12248
  .from(this.getTableName('Agent'))
12051
12249
  .select('agentSource')
12052
- .eq('agentName', agentName);
12250
+ .or(`agentName.eq.${agentName},permanentId.eq.${agentName}`);
12053
12251
  if (selectResult.data && selectResult.data.length === 0) {
12054
12252
  throw new NotFoundError(`Agent "${agentName}" not found`);
12055
12253
  }
@@ -12071,12 +12269,26 @@
12071
12269
  * Note: You can set 'PARENT' in the agent source to inherit from another agent in the collection.
12072
12270
  */
12073
12271
  async createAgent(agentSource) {
12074
- const agentProfile = parseAgentSource(agentSource);
12272
+ let agentProfile = parseAgentSource(agentSource);
12075
12273
  // <- TODO: [🕛]
12076
12274
  const { agentName, agentHash } = agentProfile;
12275
+ let { permanentId } = agentProfile;
12276
+ if (!permanentId) {
12277
+ permanentId = $randomBase58(14);
12278
+ const lines = agentSource.split('\n');
12279
+ if (lines.length > 0) {
12280
+ lines.splice(1, 0, `META ID ${permanentId}`);
12281
+ agentSource = lines.join('\n');
12282
+ }
12283
+ else {
12284
+ agentSource = `META ID ${permanentId}\n${agentSource}`;
12285
+ }
12286
+ agentProfile = parseAgentSource(agentSource);
12287
+ }
12077
12288
  const insertAgentResult = await this.supabaseClient.from(this.getTableName('Agent')).insert({
12078
12289
  agentName,
12079
12290
  agentHash,
12291
+ permanentId,
12080
12292
  agentProfile,
12081
12293
  createdAt: new Date().toISOString(),
12082
12294
  updatedAt: null,
@@ -12100,15 +12312,16 @@
12100
12312
  promptbookEngineVersion: PROMPTBOOK_ENGINE_VERSION,
12101
12313
  });
12102
12314
  // <- TODO: [🧠] What to do with `insertAgentHistoryResult.error`, ignore? wait?
12103
- return agentProfile;
12315
+ return { ...agentProfile, permanentId };
12104
12316
  }
12105
12317
  /**
12106
12318
  * Updates an existing agent in the collection
12107
12319
  */
12108
12320
  async updateAgentSource(agentName, agentSource) {
12321
+ console.log('!!! updateAgentSource', { agentName });
12109
12322
  const selectPreviousAgentResult = await this.supabaseClient
12110
12323
  .from(this.getTableName('Agent'))
12111
- .select('agentHash,agentName')
12324
+ .select('agentHash,agentName,permanentId')
12112
12325
  .eq('agentName', agentName)
12113
12326
  .single();
12114
12327
  if (selectPreviousAgentResult.error) {
@@ -12122,13 +12335,28 @@
12122
12335
  }
12123
12336
  selectPreviousAgentResult.data.agentName;
12124
12337
  const previousAgentHash = selectPreviousAgentResult.data.agentHash;
12125
- const agentProfile = parseAgentSource(agentSource);
12338
+ const previousPermanentId = selectPreviousAgentResult.data.permanentId;
12339
+ let agentProfile = parseAgentSource(agentSource);
12126
12340
  // <- TODO: [🕛]
12127
12341
  const { agentHash } = agentProfile;
12342
+ let { permanentId } = agentProfile;
12343
+ if (!permanentId && previousPermanentId) {
12344
+ permanentId = previousPermanentId;
12345
+ const lines = agentSource.split('\n');
12346
+ if (lines.length > 0) {
12347
+ lines.splice(1, 0, `META ID ${permanentId}`);
12348
+ agentSource = lines.join('\n');
12349
+ }
12350
+ else {
12351
+ agentSource = `META ID ${permanentId}\n${agentSource}`;
12352
+ }
12353
+ agentProfile = parseAgentSource(agentSource);
12354
+ }
12128
12355
  const updateAgentResult = await this.supabaseClient
12129
12356
  .from(this.getTableName('Agent'))
12130
12357
  .update({
12131
12358
  // TODO: [🐱‍🚀] Compare not update> agentName: agentProfile.agentName || '[🐱‍🚀]' /* <- TODO: [🐱‍🚀] Remove */,
12359
+ permanentId,
12132
12360
  agentProfile,
12133
12361
  updatedAt: new Date().toISOString(),
12134
12362
  agentHash: agentProfile.agentHash,
@@ -12159,20 +12387,39 @@
12159
12387
  // TODO: [🐱‍🚀] public async getAgentSourceSubject(agentName: string_agent_name): Promise<BehaviorSubject<string_book>>
12160
12388
  // Use Supabase realtime logic
12161
12389
  /**
12162
- * Deletes an agent from the collection
12390
+ * List agents that are soft deleted (deletedAt IS NOT NULL)
12163
12391
  */
12164
- async deleteAgent(agentName) {
12165
- const deleteResult = await this.supabaseClient
12392
+ async listDeletedAgents() {
12393
+ const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
12394
+ const selectResult = await this.supabaseClient
12166
12395
  .from(this.getTableName('Agent'))
12167
- .delete()
12168
- .eq('agentName', agentName);
12169
- if (deleteResult.error) {
12396
+ .select('agentName,agentProfile,permanentId')
12397
+ .not('deletedAt', 'is', null);
12398
+ if (selectResult.error) {
12170
12399
  throw new DatabaseError(spaceTrim((block) => `
12171
- Error deleting agent "${agentName}" from Supabase:
12172
-
12173
- ${block(deleteResult.error.message)}
12174
- `));
12400
+ Error fetching deleted agents from Supabase:
12401
+
12402
+ ${block(selectResult.error.message)}
12403
+ `));
12404
+ }
12405
+ if (isVerbose) {
12406
+ console.info(`Found ${selectResult.data.length} deleted agents in directory`);
12175
12407
  }
12408
+ return selectResult.data.map(({ agentName, agentProfile, permanentId }) => {
12409
+ if (isVerbose && agentProfile.agentName !== agentName) {
12410
+ console.warn(spaceTrim(`
12411
+ Agent name mismatch for agent "${agentName}". Using name from database.
12412
+
12413
+ agentName: "${agentName}"
12414
+ agentProfile.agentName: "${agentProfile.agentName}"
12415
+ `));
12416
+ }
12417
+ return {
12418
+ ...agentProfile,
12419
+ agentName,
12420
+ permanentId: permanentId || agentProfile.permanentId,
12421
+ };
12422
+ });
12176
12423
  }
12177
12424
  /**
12178
12425
  * List history of an agent
@@ -12186,71 +12433,70 @@
12186
12433
  if (result.error) {
12187
12434
  throw new DatabaseError(spaceTrim((block) => `
12188
12435
  Error listing history for agent "${agentName}" from Supabase:
12189
-
12436
+
12190
12437
  ${block(result.error.message)}
12191
12438
  `));
12192
12439
  }
12193
12440
  return result.data;
12194
12441
  }
12195
12442
  /**
12196
- * List agents that are in history but not in the active agents list
12443
+ * Restore a soft-deleted agent by setting deletedAt to NULL
12197
12444
  */
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) {
12445
+ async restoreAgent(agentIdentifier) {
12446
+ const updateResult = await this.supabaseClient
12447
+ .from(this.getTableName('Agent'))
12448
+ .update({ deletedAt: null })
12449
+ .or(`agentName.eq.${agentIdentifier},permanentId.eq.${agentIdentifier}`)
12450
+ .not('deletedAt', 'is', null);
12451
+ if (updateResult.error) {
12209
12452
  throw new DatabaseError(spaceTrim((block) => `
12210
- Error fetching current agent names from Supabase:
12211
-
12212
- ${block(currentNamesResult.error.message)}
12453
+ Error restoring agent "${agentIdentifier}" from Supabase:
12454
+
12455
+ ${block(updateResult.error.message)}
12213
12456
  `));
12214
12457
  }
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
12458
  }
12224
12459
  /**
12225
- * Restore an agent from history
12460
+ * Restore an agent from a specific history entry
12461
+ *
12462
+ * This will update the current agent with the source from the history entry
12226
12463
  */
12227
- async restoreAgent(historyId) {
12464
+ async restoreAgentFromHistory(historyId) {
12465
+ // First, get the history entry
12228
12466
  const historyResult = await this.supabaseClient
12229
12467
  .from(this.getTableName('AgentHistory'))
12230
- .select('*')
12468
+ .select('agentName, agentSource')
12231
12469
  .eq('id', historyId)
12232
12470
  .single();
12233
12471
  if (historyResult.error) {
12234
12472
  throw new DatabaseError(spaceTrim((block) => `
12235
- Error fetching agent history item "${historyId}" from Supabase:
12236
-
12473
+ Error fetching history entry with id "${historyId}" from Supabase:
12474
+
12237
12475
  ${block(historyResult.error.message)}
12238
12476
  `));
12239
12477
  }
12478
+ if (!historyResult.data) {
12479
+ throw new NotFoundError(`History entry with id "${historyId}" not found`);
12480
+ }
12240
12481
  const { agentName, agentSource } = historyResult.data;
12241
- // Check if agent exists
12242
- const agentResult = await this.supabaseClient
12482
+ // Update the agent with the source from the history entry
12483
+ await this.updateAgentSource(agentName, agentSource);
12484
+ }
12485
+ /**
12486
+ * Soft delete an agent by setting deletedAt to current timestamp
12487
+ */
12488
+ async deleteAgent(agentIdentifier) {
12489
+ const updateResult = await this.supabaseClient
12243
12490
  .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);
12250
- }
12251
- else {
12252
- // Insert (Restore from deleted)
12253
- await this.createAgent(agentSource);
12491
+ .update({ deletedAt: new Date().toISOString() })
12492
+ .or(`agentName.eq.${agentIdentifier},permanentId.eq.${agentIdentifier}`)
12493
+ .is('deletedAt', null);
12494
+ if (updateResult.error) {
12495
+ throw new DatabaseError(spaceTrim((block) => `
12496
+ Error deleting agent "${agentIdentifier}" from Supabase:
12497
+
12498
+ ${block(updateResult.error.message)}
12499
+ `));
12254
12500
  }
12255
12501
  }
12256
12502
  /**
@@ -16468,7 +16714,7 @@
16468
16714
  ${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
16469
16715
  ${morePieces.join('; ')}
16470
16716
  `);
16471
- if ($isRunningInNode) {
16717
+ if ($isRunningInNode()) {
16472
16718
  if (isInstalled && isFullyConfigured) {
16473
16719
  providerMessage = colors__default["default"].green(providerMessage);
16474
16720
  }
@@ -17869,7 +18115,7 @@
17869
18115
  let threadMessages = [];
17870
18116
  if ('thread' in prompt && Array.isArray(prompt.thread)) {
17871
18117
  threadMessages = prompt.thread.map((msg) => ({
17872
- role: msg.role === 'assistant' ? 'assistant' : 'user',
18118
+ role: msg.sender === 'assistant' ? 'assistant' : 'user',
17873
18119
  content: msg.content,
17874
18120
  }));
17875
18121
  }