@promptbook/core 0.104.0-0 → 0.104.0-2

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 (29) hide show
  1. package/esm/index.es.js +281 -82
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/types.index.d.ts +6 -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/_common/Dropdown/Dropdown.d.ts +2 -2
  10. package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
  11. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +13 -7
  12. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +6 -0
  13. package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
  14. package/esm/typings/src/commitments/index.d.ts +2 -1
  15. package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
  16. package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
  17. package/esm/typings/src/types/typeAliases.d.ts +12 -0
  18. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
  19. package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
  20. package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
  21. package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
  22. package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
  23. package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
  24. package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
  25. package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
  26. package/esm/typings/src/version.d.ts +1 -1
  27. package/package.json +1 -1
  28. package/umd/index.umd.js +287 -88
  29. 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-0';
31
+ const PROMPTBOOK_ENGINE_VERSION = '0.104.0-2';
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(),
@@ -11469,13 +11578,14 @@
11469
11578
  *
11470
11579
  * @public exported from `@promptbook/utils`
11471
11580
  */
11472
- const $isRunningInBrowser = new Function(`
11473
- try {
11474
- return this === window;
11475
- } catch (e) {
11476
- return false;
11581
+ function $isRunningInBrowser() {
11582
+ try {
11583
+ return typeof window !== 'undefined' && typeof window.document !== 'undefined';
11584
+ }
11585
+ catch (e) {
11586
+ return false;
11587
+ }
11477
11588
  }
11478
- `);
11479
11589
  /**
11480
11590
  * TODO: [🎺]
11481
11591
  */
@@ -11487,13 +11597,15 @@
11487
11597
  *
11488
11598
  * @public exported from `@promptbook/utils`
11489
11599
  */
11490
- const $isRunningInJest = new Function(`
11491
- try {
11492
- return process.env.JEST_WORKER_ID !== undefined;
11493
- } catch (e) {
11494
- return false;
11600
+ function $isRunningInJest() {
11601
+ var _a;
11602
+ try {
11603
+ return typeof process !== 'undefined' && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.JEST_WORKER_ID) !== undefined;
11604
+ }
11605
+ catch (e) {
11606
+ return false;
11607
+ }
11495
11608
  }
11496
- `);
11497
11609
  /**
11498
11610
  * TODO: [🎺]
11499
11611
  */
@@ -11505,13 +11617,14 @@
11505
11617
  *
11506
11618
  * @public exported from `@promptbook/utils`
11507
11619
  */
11508
- const $isRunningInNode = new Function(`
11509
- try {
11510
- return this === global;
11511
- } catch (e) {
11512
- return false;
11620
+ function $isRunningInNode() {
11621
+ try {
11622
+ return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
11623
+ }
11624
+ catch (e) {
11625
+ return false;
11626
+ }
11513
11627
  }
11514
- `);
11515
11628
  /**
11516
11629
  * TODO: [🎺]
11517
11630
  */
@@ -11523,17 +11636,17 @@
11523
11636
  *
11524
11637
  * @public exported from `@promptbook/utils`
11525
11638
  */
11526
- const $isRunningInWebWorker = new Function(`
11527
- try {
11528
- if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
11529
- return true;
11530
- } else {
11639
+ function $isRunningInWebWorker() {
11640
+ try {
11641
+ // Note: Check for importScripts which is specific to workers
11642
+ // and not available in the main browser thread
11643
+ return (typeof self !== 'undefined' &&
11644
+ typeof self.importScripts === 'function');
11645
+ }
11646
+ catch (e) {
11531
11647
  return false;
11532
11648
  }
11533
- } catch (e) {
11534
- return false;
11535
11649
  }
11536
- `);
11537
11650
  /**
11538
11651
  * TODO: [🎺]
11539
11652
  */
@@ -11791,6 +11904,7 @@
11791
11904
  return {
11792
11905
  agentName: normalizeAgentName(parseResult.agentName || createDefaultAgentName(agentSource)),
11793
11906
  agentHash,
11907
+ permanentId: meta.id,
11794
11908
  personaDescription,
11795
11909
  initialMessage,
11796
11910
  meta,
@@ -11982,6 +12096,41 @@
11982
12096
  // <- [🐱‍🚀] Buttons into genesis book
11983
12097
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
11984
12098
 
12099
+ /**
12100
+ * Base58 characters
12101
+ */
12102
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
12103
+ /**
12104
+ * Generates random base58 string
12105
+ *
12106
+ * Note: `$` is used to indicate that this function is not a pure function - it is not deterministic
12107
+ * Note: This function is cryptographically secure (it uses crypto.randomBytes internally)
12108
+ *
12109
+ * @param length - length of the string
12110
+ * @returns secure random base58 string
12111
+ *
12112
+ * @private internal helper function
12113
+ */
12114
+ function $randomBase58(length) {
12115
+ let result = '';
12116
+ while (result.length < length) {
12117
+ // Generate enough bytes to cover the remaining length, plus some extra buffer to reduce calls
12118
+ // But simply generating `length - result.length` is fine for small lengths
12119
+ const bytes = crypto.randomBytes(length - result.length);
12120
+ for (let i = 0; i < bytes.length; i++) {
12121
+ const byte = bytes[i];
12122
+ // 58 * 4 = 232
12123
+ // We discard values >= 232 to avoid modulo bias
12124
+ if (byte < 232) {
12125
+ result += BASE58_ALPHABET[byte % 58];
12126
+ if (result.length === length)
12127
+ break;
12128
+ }
12129
+ }
12130
+ }
12131
+ return result;
12132
+ }
12133
+
11985
12134
  // import { getTableName } from '../../../../../apps/agents-server/src/database/getTableName';
11986
12135
  // <- TODO: [🐱‍🚀] Prevent imports from `/apps` -> `/src`
11987
12136
  /**
@@ -12015,19 +12164,20 @@
12015
12164
  const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
12016
12165
  const selectResult = await this.supabaseClient
12017
12166
  .from(this.getTableName('Agent'))
12018
- .select('agentName,agentProfile');
12167
+ .select('agentName,agentProfile,permanentId')
12168
+ .is('deletedAt', null);
12019
12169
  if (selectResult.error) {
12020
12170
  throw new DatabaseError(spaceTrim((block) => `
12021
-
12171
+
12022
12172
  Error fetching agents from Supabase:
12023
-
12173
+
12024
12174
  ${block(selectResult.error.message)}
12025
12175
  `));
12026
12176
  }
12027
12177
  if (isVerbose) {
12028
12178
  console.info(`Found ${selectResult.data.length} agents in directory`);
12029
12179
  }
12030
- return selectResult.data.map(({ agentName, agentProfile }) => {
12180
+ return selectResult.data.map(({ agentName, agentProfile, permanentId }) => {
12031
12181
  if (isVerbose && agentProfile.agentName !== agentName) {
12032
12182
  console.warn(spaceTrim(`
12033
12183
  Agent name mismatch for agent "${agentName}". Using name from database.
@@ -12039,6 +12189,7 @@
12039
12189
  return {
12040
12190
  ...agentProfile,
12041
12191
  agentName,
12192
+ permanentId: permanentId || agentProfile.permanentId,
12042
12193
  };
12043
12194
  });
12044
12195
  }
@@ -12049,7 +12200,7 @@
12049
12200
  const selectResult = await this.supabaseClient
12050
12201
  .from(this.getTableName('Agent'))
12051
12202
  .select('agentSource')
12052
- .eq('agentName', agentName);
12203
+ .or(`agentName.eq.${agentName},permanentId.eq.${agentName}`);
12053
12204
  if (selectResult.data && selectResult.data.length === 0) {
12054
12205
  throw new NotFoundError(`Agent "${agentName}" not found`);
12055
12206
  }
@@ -12071,12 +12222,26 @@
12071
12222
  * Note: You can set 'PARENT' in the agent source to inherit from another agent in the collection.
12072
12223
  */
12073
12224
  async createAgent(agentSource) {
12074
- const agentProfile = parseAgentSource(agentSource);
12225
+ let agentProfile = parseAgentSource(agentSource);
12075
12226
  // <- TODO: [🕛]
12076
12227
  const { agentName, agentHash } = agentProfile;
12228
+ let { permanentId } = agentProfile;
12229
+ if (!permanentId) {
12230
+ permanentId = $randomBase58(14);
12231
+ const lines = agentSource.split('\n');
12232
+ if (lines.length > 0) {
12233
+ lines.splice(1, 0, `META ID ${permanentId}`);
12234
+ agentSource = lines.join('\n');
12235
+ }
12236
+ else {
12237
+ agentSource = `META ID ${permanentId}\n${agentSource}`;
12238
+ }
12239
+ agentProfile = parseAgentSource(agentSource);
12240
+ }
12077
12241
  const insertAgentResult = await this.supabaseClient.from(this.getTableName('Agent')).insert({
12078
12242
  agentName,
12079
12243
  agentHash,
12244
+ permanentId,
12080
12245
  agentProfile,
12081
12246
  createdAt: new Date().toISOString(),
12082
12247
  updatedAt: null,
@@ -12100,15 +12265,16 @@
12100
12265
  promptbookEngineVersion: PROMPTBOOK_ENGINE_VERSION,
12101
12266
  });
12102
12267
  // <- TODO: [🧠] What to do with `insertAgentHistoryResult.error`, ignore? wait?
12103
- return agentProfile;
12268
+ return { ...agentProfile, permanentId };
12104
12269
  }
12105
12270
  /**
12106
12271
  * Updates an existing agent in the collection
12107
12272
  */
12108
12273
  async updateAgentSource(agentName, agentSource) {
12274
+ console.log('!!! updateAgentSource', { agentName });
12109
12275
  const selectPreviousAgentResult = await this.supabaseClient
12110
12276
  .from(this.getTableName('Agent'))
12111
- .select('agentHash,agentName')
12277
+ .select('agentHash,agentName,permanentId')
12112
12278
  .eq('agentName', agentName)
12113
12279
  .single();
12114
12280
  if (selectPreviousAgentResult.error) {
@@ -12122,13 +12288,28 @@
12122
12288
  }
12123
12289
  selectPreviousAgentResult.data.agentName;
12124
12290
  const previousAgentHash = selectPreviousAgentResult.data.agentHash;
12125
- const agentProfile = parseAgentSource(agentSource);
12291
+ const previousPermanentId = selectPreviousAgentResult.data.permanentId;
12292
+ let agentProfile = parseAgentSource(agentSource);
12126
12293
  // <- TODO: [🕛]
12127
12294
  const { agentHash } = agentProfile;
12295
+ let { permanentId } = agentProfile;
12296
+ if (!permanentId && previousPermanentId) {
12297
+ permanentId = previousPermanentId;
12298
+ const lines = agentSource.split('\n');
12299
+ if (lines.length > 0) {
12300
+ lines.splice(1, 0, `META ID ${permanentId}`);
12301
+ agentSource = lines.join('\n');
12302
+ }
12303
+ else {
12304
+ agentSource = `META ID ${permanentId}\n${agentSource}`;
12305
+ }
12306
+ agentProfile = parseAgentSource(agentSource);
12307
+ }
12128
12308
  const updateAgentResult = await this.supabaseClient
12129
12309
  .from(this.getTableName('Agent'))
12130
12310
  .update({
12131
12311
  // TODO: [🐱‍🚀] Compare not update> agentName: agentProfile.agentName || '[🐱‍🚀]' /* <- TODO: [🐱‍🚀] Remove */,
12312
+ permanentId,
12132
12313
  agentProfile,
12133
12314
  updatedAt: new Date().toISOString(),
12134
12315
  agentHash: agentProfile.agentHash,
@@ -12159,20 +12340,39 @@
12159
12340
  // TODO: [🐱‍🚀] public async getAgentSourceSubject(agentName: string_agent_name): Promise<BehaviorSubject<string_book>>
12160
12341
  // Use Supabase realtime logic
12161
12342
  /**
12162
- * Deletes an agent from the collection
12343
+ * List agents that are soft deleted (deletedAt IS NOT NULL)
12163
12344
  */
12164
- async deleteAgent(agentName) {
12165
- const deleteResult = await this.supabaseClient
12345
+ async listDeletedAgents() {
12346
+ const { isVerbose = exports.DEFAULT_IS_VERBOSE } = this.options || {};
12347
+ const selectResult = await this.supabaseClient
12166
12348
  .from(this.getTableName('Agent'))
12167
- .delete()
12168
- .eq('agentName', agentName);
12169
- if (deleteResult.error) {
12349
+ .select('agentName,agentProfile,permanentId')
12350
+ .not('deletedAt', 'is', null);
12351
+ if (selectResult.error) {
12170
12352
  throw new DatabaseError(spaceTrim((block) => `
12171
- Error deleting agent "${agentName}" from Supabase:
12172
-
12173
- ${block(deleteResult.error.message)}
12174
- `));
12353
+ Error fetching deleted agents from Supabase:
12354
+
12355
+ ${block(selectResult.error.message)}
12356
+ `));
12175
12357
  }
12358
+ if (isVerbose) {
12359
+ console.info(`Found ${selectResult.data.length} deleted agents in directory`);
12360
+ }
12361
+ return selectResult.data.map(({ agentName, agentProfile, permanentId }) => {
12362
+ if (isVerbose && agentProfile.agentName !== agentName) {
12363
+ console.warn(spaceTrim(`
12364
+ Agent name mismatch for agent "${agentName}". Using name from database.
12365
+
12366
+ agentName: "${agentName}"
12367
+ agentProfile.agentName: "${agentProfile.agentName}"
12368
+ `));
12369
+ }
12370
+ return {
12371
+ ...agentProfile,
12372
+ agentName,
12373
+ permanentId: permanentId || agentProfile.permanentId,
12374
+ };
12375
+ });
12176
12376
  }
12177
12377
  /**
12178
12378
  * List history of an agent
@@ -12186,71 +12386,70 @@
12186
12386
  if (result.error) {
12187
12387
  throw new DatabaseError(spaceTrim((block) => `
12188
12388
  Error listing history for agent "${agentName}" from Supabase:
12189
-
12389
+
12190
12390
  ${block(result.error.message)}
12191
12391
  `));
12192
12392
  }
12193
12393
  return result.data;
12194
12394
  }
12195
12395
  /**
12196
- * List agents that are in history but not in the active agents list
12396
+ * Restore a soft-deleted agent by setting deletedAt to NULL
12197
12397
  */
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) {
12398
+ async restoreAgent(agentIdentifier) {
12399
+ const updateResult = await this.supabaseClient
12400
+ .from(this.getTableName('Agent'))
12401
+ .update({ deletedAt: null })
12402
+ .or(`agentName.eq.${agentIdentifier},permanentId.eq.${agentIdentifier}`)
12403
+ .not('deletedAt', 'is', null);
12404
+ if (updateResult.error) {
12209
12405
  throw new DatabaseError(spaceTrim((block) => `
12210
- Error fetching current agent names from Supabase:
12211
-
12212
- ${block(currentNamesResult.error.message)}
12406
+ Error restoring agent "${agentIdentifier}" from Supabase:
12407
+
12408
+ ${block(updateResult.error.message)}
12213
12409
  `));
12214
12410
  }
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
12411
  }
12224
12412
  /**
12225
- * Restore an agent from history
12413
+ * Restore an agent from a specific history entry
12414
+ *
12415
+ * This will update the current agent with the source from the history entry
12226
12416
  */
12227
- async restoreAgent(historyId) {
12417
+ async restoreAgentFromHistory(historyId) {
12418
+ // First, get the history entry
12228
12419
  const historyResult = await this.supabaseClient
12229
12420
  .from(this.getTableName('AgentHistory'))
12230
- .select('*')
12421
+ .select('agentName, agentSource')
12231
12422
  .eq('id', historyId)
12232
12423
  .single();
12233
12424
  if (historyResult.error) {
12234
12425
  throw new DatabaseError(spaceTrim((block) => `
12235
- Error fetching agent history item "${historyId}" from Supabase:
12236
-
12426
+ Error fetching history entry with id "${historyId}" from Supabase:
12427
+
12237
12428
  ${block(historyResult.error.message)}
12238
12429
  `));
12239
12430
  }
12431
+ if (!historyResult.data) {
12432
+ throw new NotFoundError(`History entry with id "${historyId}" not found`);
12433
+ }
12240
12434
  const { agentName, agentSource } = historyResult.data;
12241
- // Check if agent exists
12242
- const agentResult = await this.supabaseClient
12435
+ // Update the agent with the source from the history entry
12436
+ await this.updateAgentSource(agentName, agentSource);
12437
+ }
12438
+ /**
12439
+ * Soft delete an agent by setting deletedAt to current timestamp
12440
+ */
12441
+ async deleteAgent(agentIdentifier) {
12442
+ const updateResult = await this.supabaseClient
12243
12443
  .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);
12444
+ .update({ deletedAt: new Date().toISOString() })
12445
+ .or(`agentName.eq.${agentIdentifier},permanentId.eq.${agentIdentifier}`)
12446
+ .is('deletedAt', null);
12447
+ if (updateResult.error) {
12448
+ throw new DatabaseError(spaceTrim((block) => `
12449
+ Error deleting agent "${agentIdentifier}" from Supabase:
12450
+
12451
+ ${block(updateResult.error.message)}
12452
+ `));
12254
12453
  }
12255
12454
  }
12256
12455
  /**
@@ -16468,7 +16667,7 @@
16468
16667
  ${i + 1}) **${title}** \`${className}\` from \`${packageName}\`
16469
16668
  ${morePieces.join('; ')}
16470
16669
  `);
16471
- if ($isRunningInNode) {
16670
+ if ($isRunningInNode()) {
16472
16671
  if (isInstalled && isFullyConfigured) {
16473
16672
  providerMessage = colors__default["default"].green(providerMessage);
16474
16673
  }