@promptbook/browser 0.104.0-9 → 0.105.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/esm/index.es.js +266 -46
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/components.index.d.ts +0 -6
  4. package/esm/typings/src/_packages/core.index.d.ts +10 -6
  5. package/esm/typings/src/_packages/types.index.d.ts +8 -0
  6. package/esm/typings/src/_packages/utils.index.d.ts +2 -0
  7. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +24 -0
  8. package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +16 -2
  9. package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirements.tools.test.d.ts +1 -0
  10. package/esm/typings/src/book-2.0/utils/generatePlaceholderAgentProfileImageUrl.d.ts +1 -1
  11. package/esm/typings/src/book-components/Chat/save/_common/string_chat_format_name.d.ts +1 -1
  12. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +23 -3
  13. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +5 -1
  14. package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +5 -1
  15. package/esm/typings/src/book-components/icons/AboutIcon.d.ts +5 -1
  16. package/esm/typings/src/book-components/icons/AttachmentIcon.d.ts +6 -2
  17. package/esm/typings/src/book-components/icons/CameraIcon.d.ts +6 -2
  18. package/esm/typings/src/book-components/icons/DownloadIcon.d.ts +5 -1
  19. package/esm/typings/src/book-components/icons/MenuIcon.d.ts +5 -1
  20. package/esm/typings/src/book-components/icons/SaveIcon.d.ts +6 -2
  21. package/esm/typings/src/collection/agent-collection/AgentCollection.d.ts +1 -1
  22. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +9 -7
  23. package/esm/typings/src/commands/_common/types/Command.d.ts +1 -1
  24. package/esm/typings/src/commitments/IMPORT/IMPORT.d.ts +34 -0
  25. package/esm/typings/src/commitments/META/META_DESCRIPTION.d.ts +41 -0
  26. package/esm/typings/src/commitments/USE_SEARCH_ENGINE/USE_SEARCH_ENGINE.d.ts +2 -2
  27. package/esm/typings/src/commitments/_base/BookCommitment.d.ts +1 -1
  28. package/esm/typings/src/commitments/index.d.ts +2 -1
  29. package/esm/typings/src/config.d.ts +14 -1
  30. package/esm/typings/src/errors/utils/deserializeError.d.ts +1 -1
  31. package/esm/typings/src/execution/PromptResult.d.ts +24 -1
  32. package/esm/typings/src/formfactors/_common/FormfactorDefinition.d.ts +1 -1
  33. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +1 -1
  34. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizardOrCli.d.ts +1 -1
  35. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/LlmExecutionToolsWithTotalUsage.d.ts +1 -1
  36. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/countUsage.d.ts +8 -4
  37. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/limitTotalUsage.d.ts +1 -1
  38. package/esm/typings/src/llm-providers/_multiple/getSingleLlmExecutionTools.d.ts +1 -1
  39. package/esm/typings/src/llm-providers/_multiple/joinLlmExecutionTools.d.ts +12 -8
  40. package/esm/typings/src/llm-providers/agent/Agent.d.ts +7 -1
  41. package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +1 -1
  42. package/esm/typings/src/llm-providers/openai/OpenAiCompatibleExecutionToolsOptions.d.ts +5 -0
  43. package/esm/typings/src/llm-providers/openai/utils/mapToolsToOpenAi.d.ts +8 -0
  44. package/esm/typings/src/remote-server/ui/ServerApp.d.ts +5 -1
  45. package/esm/typings/src/scrapers/_common/utils/promptbookFetch.test.d.ts +1 -0
  46. package/esm/typings/src/search-engines/SearchEngine.d.ts +9 -0
  47. package/esm/typings/src/search-engines/SearchResult.d.ts +18 -0
  48. package/esm/typings/src/search-engines/bing/BingSearchEngine.d.ts +15 -0
  49. package/esm/typings/src/search-engines/dummy/DummySearchEngine.d.ts +15 -0
  50. package/esm/typings/src/types/LlmToolDefinition.d.ts +27 -0
  51. package/esm/typings/src/types/ModelRequirements.d.ts +13 -0
  52. package/esm/typings/src/types/Prompt.d.ts +13 -0
  53. package/esm/typings/src/types/typeAliasEmoji.d.ts +2 -2
  54. package/esm/typings/src/utils/misc/parseNumber.d.ts +1 -1
  55. package/esm/typings/src/utils/random/$randomAgentPersona.d.ts +7 -2
  56. package/esm/typings/src/utils/random/$randomItem.d.ts +1 -1
  57. package/esm/typings/src/utils/random/$randomSeed.d.ts +1 -1
  58. package/esm/typings/src/utils/validators/url/isValidAgentUrl.d.ts +16 -0
  59. package/esm/typings/src/utils/validators/url/isValidAgentUrl.test.d.ts +1 -0
  60. package/esm/typings/src/utils/validators/url/isValidPipelineUrl.d.ts +2 -1
  61. package/esm/typings/src/utils/validators/url/isValidUrl.d.ts +4 -3
  62. package/esm/typings/src/version.d.ts +1 -1
  63. package/package.json +2 -2
  64. package/umd/index.umd.js +266 -46
  65. package/umd/index.umd.js.map +1 -1
  66. package/esm/typings/servers.d.ts +0 -50
package/esm/index.es.js CHANGED
@@ -19,7 +19,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
19
19
  * @generated
20
20
  * @see https://github.com/webgptorg/promptbook
21
21
  */
22
- const PROMPTBOOK_ENGINE_VERSION = '0.104.0-9';
22
+ const PROMPTBOOK_ENGINE_VERSION = '0.105.0-0';
23
23
  /**
24
24
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
25
25
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2208,9 +2208,10 @@ function isValidFilePath(filename) {
2208
2208
  *
2209
2209
  * Note: [🔂] This function is idempotent.
2210
2210
  * Note: Dataurl are considered perfectly valid.
2211
- * Note: There are two similar functions:
2212
- * - `isValidUrl` which tests any URL
2213
- * - `isValidPipelineUrl` *(this one)* which tests just promptbook URL
2211
+ * Note: There are few similar functions:
2212
+ * - `isValidUrl` *(this one)* which tests any URL
2213
+ * - `isValidAgentUrl` which tests just agent URL
2214
+ * - `isValidPipelineUrl` which tests just pipeline URL
2214
2215
  *
2215
2216
  * @public exported from `@promptbook/utils`
2216
2217
  */
@@ -2488,8 +2489,8 @@ for (let i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
2488
2489
  */
2489
2490
  function removeDiacritics(input) {
2490
2491
  /*eslint no-control-regex: "off"*/
2491
- return input.replace(/[^\u0000-\u007E]/g, (a) => {
2492
- return DIACRITIC_VARIANTS_LETTERS[a] || a;
2492
+ return input.replace(/[^\u0000-\u007E]/g, (character) => {
2493
+ return DIACRITIC_VARIANTS_LETTERS[character] || character;
2493
2494
  });
2494
2495
  }
2495
2496
  /**
@@ -2620,6 +2621,39 @@ function titleToName(value) {
2620
2621
  * Note: [💞] Ignore a discrepancy between file name and entity name
2621
2622
  */
2622
2623
 
2624
+ /**
2625
+ * Tests if given string is valid agent URL
2626
+ *
2627
+ * Note: There are few similar functions:
2628
+ * - `isValidUrl` which tests any URL
2629
+ * - `isValidAgentUrl` *(this one)* which tests just agent URL
2630
+ * - `isValidPipelineUrl` which tests just pipeline URL
2631
+ *
2632
+ * @public exported from `@promptbook/utils`
2633
+ */
2634
+ function isValidAgentUrl(url) {
2635
+ if (!isValidUrl(url)) {
2636
+ return false;
2637
+ }
2638
+ if (!url.startsWith('https://') && !url.startsWith('http://') /* <- Note: [👣] */) {
2639
+ return false;
2640
+ }
2641
+ if (url.includes('#')) {
2642
+ // TODO: [🐠]
2643
+ return false;
2644
+ }
2645
+ /*
2646
+ Note: [👣][🧠] Is it secure to allow pipeline URLs on private and unsecured networks?
2647
+ if (isUrlOnPrivateNetwork(url)) {
2648
+ return false;
2649
+ }
2650
+ */
2651
+ return true;
2652
+ }
2653
+ /**
2654
+ * TODO: [🐠] Maybe more info why the URL is invalid
2655
+ */
2656
+
2623
2657
  /**
2624
2658
  * Normalizes agent name from arbitrary string to valid agent name
2625
2659
  *
@@ -2651,8 +2685,8 @@ function createDefaultAgentName(agentSource) {
2651
2685
  */
2652
2686
  function createCommitmentRegex(commitment, aliases = [], requiresContent = true) {
2653
2687
  const allCommitments = [commitment, ...aliases];
2654
- const patterns = allCommitments.map((c) => {
2655
- const escapedCommitment = c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2688
+ const patterns = allCommitments.map((commitment) => {
2689
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2656
2690
  return escapedCommitment.split(/\s+/).join('\\s+');
2657
2691
  });
2658
2692
  const keywordPattern = patterns.join('|');
@@ -2674,8 +2708,8 @@ function createCommitmentRegex(commitment, aliases = [], requiresContent = true)
2674
2708
  */
2675
2709
  function createCommitmentTypeRegex(commitment, aliases = []) {
2676
2710
  const allCommitments = [commitment, ...aliases];
2677
- const patterns = allCommitments.map((c) => {
2678
- const escapedCommitment = c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2711
+ const patterns = allCommitments.map((commitment) => {
2712
+ const escapedCommitment = commitment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2679
2713
  return escapedCommitment.split(/\s+/).join('\\s+');
2680
2714
  });
2681
2715
  const keywordPattern = patterns.join('|');
@@ -3185,9 +3219,7 @@ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
3185
3219
  // Get existing dictionary entries from metadata
3186
3220
  const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
3187
3221
  // Merge the new dictionary entry with existing entries
3188
- const mergedDictionary = existingDictionary
3189
- ? `${existingDictionary}\n${trimmedContent}`
3190
- : trimmedContent;
3222
+ const mergedDictionary = existingDictionary ? `${existingDictionary}\n${trimmedContent}` : trimmedContent;
3191
3223
  // Store the merged dictionary in metadata for debugging and inspection
3192
3224
  const updatedMetadata = {
3193
3225
  ...requirements.metadata,
@@ -3338,21 +3370,108 @@ class FromCommitmentDefinition extends BaseCommitmentDefinition {
3338
3370
  applyToAgentModelRequirements(requirements, content) {
3339
3371
  const trimmedContent = content.trim();
3340
3372
  if (!trimmedContent) {
3341
- return requirements;
3373
+ return {
3374
+ ...requirements,
3375
+ parentAgentUrl: undefined,
3376
+ };
3342
3377
  }
3343
- // Validate URL
3344
- try {
3345
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
3346
- const url = new URL(trimmedContent);
3347
- // TODO: Add more validation if needed (e.g. check for valid protocol)
3378
+ if (trimmedContent.toUpperCase() === 'VOID' ||
3379
+ trimmedContent.toUpperCase() === 'NULL' ||
3380
+ trimmedContent.toUpperCase() === 'NONE' ||
3381
+ trimmedContent.toUpperCase() === 'NIL') {
3382
+ return {
3383
+ ...requirements,
3384
+ parentAgentUrl: null,
3385
+ };
3348
3386
  }
3349
- catch (error) {
3350
- console.warn(`Invalid URL in FROM commitment: ${trimmedContent}`);
3387
+ if (!isValidAgentUrl(trimmedContent)) {
3388
+ throw new Error(spaceTrim$1((block) => `
3389
+ Invalid agent URL in FROM commitment: "${trimmedContent}"
3390
+
3391
+ \`\`\`book
3392
+ ${block(content)}
3393
+ \`\`\`
3394
+
3395
+
3396
+ `));
3397
+ }
3398
+ const parentAgentUrl = trimmedContent;
3399
+ return {
3400
+ ...requirements,
3401
+ parentAgentUrl,
3402
+ };
3403
+ }
3404
+ }
3405
+ /**
3406
+ * Note: [💞] Ignore a discrepancy between file name and entity name
3407
+ */
3408
+
3409
+ /**
3410
+ * IMPORT commitment definition
3411
+ *
3412
+ * The IMPORT commitment tells the agent to import content from another agent at the current location.
3413
+ *
3414
+ * Example usage in agent source:
3415
+ *
3416
+ * ```book
3417
+ * IMPORT https://s6.ptbk.io/benjamin-white
3418
+ * ```
3419
+ *
3420
+ * @private [🪔] Maybe export the commitments through some package
3421
+ */
3422
+ class ImportCommitmentDefinition extends BaseCommitmentDefinition {
3423
+ constructor(type = 'IMPORT') {
3424
+ super(type);
3425
+ }
3426
+ /**
3427
+ * Short one-line description of IMPORT.
3428
+ */
3429
+ get description() {
3430
+ return 'Import content from another agent.';
3431
+ }
3432
+ /**
3433
+ * Icon for this commitment.
3434
+ */
3435
+ get icon() {
3436
+ return '📥';
3437
+ }
3438
+ /**
3439
+ * Markdown documentation for IMPORT commitment.
3440
+ */
3441
+ get documentation() {
3442
+ return spaceTrim$1(`
3443
+ # ${this.type}
3444
+
3445
+ Imports content from another agent at the location of the commitment.
3446
+
3447
+ ## Examples
3448
+
3449
+ \`\`\`book
3450
+ My AI Agent
3451
+
3452
+ IMPORT https://s6.ptbk.io/benjamin-white
3453
+ RULE Speak only in English.
3454
+ \`\`\`
3455
+ `);
3456
+ }
3457
+ applyToAgentModelRequirements(requirements, content) {
3458
+ const trimmedContent = content.trim();
3459
+ if (!trimmedContent) {
3351
3460
  return requirements;
3352
3461
  }
3462
+ if (!isValidAgentUrl(trimmedContent)) {
3463
+ throw new Error(spaceTrim$1((block) => `
3464
+ Invalid agent URL in IMPORT commitment: "${trimmedContent}"
3465
+
3466
+ \`\`\`book
3467
+ ${block(content)}
3468
+ \`\`\`
3469
+ `));
3470
+ }
3471
+ const importedAgentUrl = trimmedContent;
3353
3472
  return {
3354
3473
  ...requirements,
3355
- parentAgentUrl: trimmedContent,
3474
+ importedAgentUrls: [...(requirements.importedAgentUrls || []), importedAgentUrl],
3356
3475
  };
3357
3476
  }
3358
3477
  }
@@ -5716,19 +5835,38 @@ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
5716
5835
  `);
5717
5836
  }
5718
5837
  applyToAgentModelRequirements(requirements, content) {
5719
- // We simply mark that browser capability is enabled in metadata
5720
- // Get existing metadata
5721
- const existingMetadata = requirements.metadata || {};
5722
5838
  // Get existing tools array or create new one
5723
- const existingTools = existingMetadata.tools || [];
5724
- // Add 'browser' to tools if not already present
5725
- const updatedTools = existingTools.includes('browser') ? existingTools : [...existingTools, 'browser'];
5726
- // Return requirements with updated metadata
5839
+ const existingTools = requirements.tools || [];
5840
+ // Add 'web_browser' to tools if not already present
5841
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_browser')
5842
+ ? existingTools
5843
+ : ([
5844
+ // TODO: [🔰] Use through proper MCP server
5845
+ ...existingTools,
5846
+ {
5847
+ name: 'web_browser',
5848
+ description: spaceTrim$1(`
5849
+ A tool that can browse the web.
5850
+ Use this tool when you need to access specific websites or browse the internet.
5851
+ `),
5852
+ parameters: {
5853
+ type: 'object',
5854
+ properties: {
5855
+ url: {
5856
+ type: 'string',
5857
+ description: 'The URL to browse',
5858
+ },
5859
+ },
5860
+ required: ['url'],
5861
+ },
5862
+ },
5863
+ ]);
5864
+ // Return requirements with updated tools and metadata
5727
5865
  return {
5728
5866
  ...requirements,
5867
+ tools: updatedTools,
5729
5868
  metadata: {
5730
- ...existingMetadata,
5731
- tools: updatedTools,
5869
+ ...requirements.metadata,
5732
5870
  useBrowser: true,
5733
5871
  },
5734
5872
  };
@@ -5821,13 +5959,13 @@ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
5821
5959
  * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
5822
5960
  * to access and retrieve up-to-date information from the internet when necessary.
5823
5961
  *
5824
- * The content following `USE SEARCH ENGINE` is ignored (similar to NOTE).
5962
+ * The content following `USE SEARCH ENGINE` is an arbitrary text that the agent should know (e.g. search scope or instructions).
5825
5963
  *
5826
5964
  * Example usage in agent source:
5827
5965
  *
5828
5966
  * ```book
5829
5967
  * USE SEARCH ENGINE
5830
- * USE SEARCH ENGINE This will be ignored
5968
+ * USE SEARCH ENGINE Hledej informace o Přemyslovcích
5831
5969
  * ```
5832
5970
  *
5833
5971
  * @private [🪔] Maybe export the commitments through some package
@@ -5859,7 +5997,7 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
5859
5997
 
5860
5998
  ## Key aspects
5861
5999
 
5862
- - The content following \`USE SEARCH ENGINE\` is ignored (similar to NOTE)
6000
+ - The content following \`USE SEARCH ENGINE\` is an arbitrary text that the agent should know (e.g. search scope or instructions).
5863
6001
  - The actual search engine tool usage is handled by the agent runtime
5864
6002
  - Allows the agent to search for current information from the web
5865
6003
  - Useful for research tasks, finding facts, and accessing dynamic content
@@ -5884,20 +6022,45 @@ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
5884
6022
  `);
5885
6023
  }
5886
6024
  applyToAgentModelRequirements(requirements, content) {
5887
- // We simply mark that search engine capability is enabled in metadata
5888
- // Get existing metadata
5889
- const existingMetadata = requirements.metadata || {};
5890
6025
  // Get existing tools array or create new one
5891
- const existingTools = existingMetadata.tools || [];
5892
- // Add 'search-engine' to tools if not already present
5893
- const updatedTools = existingTools.includes('search-engine') ? existingTools : [...existingTools, 'search-engine'];
5894
- // Return requirements with updated metadata
6026
+ const existingTools = requirements.tools || [];
6027
+ // Add 'web_search' to tools if not already present
6028
+ const updatedTools = existingTools.some((tool) => tool.name === 'web_search')
6029
+ ? existingTools
6030
+ : [
6031
+ ...existingTools,
6032
+ { type: 'web_search' },
6033
+ // <- Note: [🔰] This is just using simple native search tool by OpenAI @see https://platform.openai.com/docs/guides/tools-web-search
6034
+ // In future we will use proper MCP search tool:
6035
+ /*
6036
+
6037
+ {
6038
+ name: 'web_search',
6039
+ description: spaceTrim(`
6040
+ Search the internet for information.
6041
+ Use this tool when you need to find up-to-date information or facts that you don't know.
6042
+ ${!content ? '' : `Search scope / instructions: ${content}`}
6043
+ `),
6044
+ parameters: {
6045
+ type: 'object',
6046
+ properties: {
6047
+ query: {
6048
+ type: 'string',
6049
+ description: 'The search query',
6050
+ },
6051
+ },
6052
+ required: ['query'],
6053
+ },
6054
+ },
6055
+ */
6056
+ ];
6057
+ // Return requirements with updated tools and metadata
5895
6058
  return {
5896
6059
  ...requirements,
6060
+ tools: updatedTools,
5897
6061
  metadata: {
5898
- ...existingMetadata,
5899
- tools: updatedTools,
5900
- useSearchEngine: true,
6062
+ ...requirements.metadata,
6063
+ useSearchEngine: content || true,
5901
6064
  },
5902
6065
  };
5903
6066
  }
@@ -5999,6 +6162,8 @@ const COMMITMENT_REGISTRY = [
5999
6162
  new FormatCommitmentDefinition('FORMAT'),
6000
6163
  new FormatCommitmentDefinition('FORMATS'),
6001
6164
  new FromCommitmentDefinition('FROM'),
6165
+ new ImportCommitmentDefinition('IMPORT'),
6166
+ new ImportCommitmentDefinition('IMPORTS'),
6002
6167
  new ModelCommitmentDefinition('MODEL'),
6003
6168
  new ModelCommitmentDefinition('MODELS'),
6004
6169
  new ActionCommitmentDefinition('ACTION'),
@@ -6258,8 +6423,8 @@ function parseParameters(text) {
6258
6423
  return match;
6259
6424
  });
6260
6425
  // Remove duplicates based on name (keep the first occurrence)
6261
- const uniqueParameters = parameters.filter((param, index, array) => {
6262
- return array.findIndex((p) => p.name === param.name) === index;
6426
+ const uniqueParameters = parameters.filter((parameter, index, array) => {
6427
+ return array.findIndex((parameterItem) => parameterItem.name === parameter.name) === index;
6263
6428
  });
6264
6429
  return uniqueParameters;
6265
6430
  }
@@ -6301,7 +6466,57 @@ function parseAgentSource(agentSource) {
6301
6466
  }
6302
6467
  const meta = {};
6303
6468
  const links = [];
6469
+ const capabilities = [];
6304
6470
  for (const commitment of parseResult.commitments) {
6471
+ if (commitment.type === 'USE BROWSER') {
6472
+ capabilities.push({
6473
+ type: 'browser',
6474
+ label: 'Browser',
6475
+ iconName: 'Globe',
6476
+ });
6477
+ continue;
6478
+ }
6479
+ if (commitment.type === 'USE SEARCH ENGINE') {
6480
+ capabilities.push({
6481
+ type: 'search-engine',
6482
+ label: 'Search Internet',
6483
+ iconName: 'Search',
6484
+ });
6485
+ continue;
6486
+ }
6487
+ if (commitment.type === 'KNOWLEDGE') {
6488
+ const content = spaceTrim$2(commitment.content).split('\n')[0] || '';
6489
+ let label = content;
6490
+ let iconName = 'Book';
6491
+ if (content.startsWith('http://') || content.startsWith('https://')) {
6492
+ try {
6493
+ const url = new URL(content);
6494
+ if (url.pathname.endsWith('.pdf')) {
6495
+ label = url.pathname.split('/').pop() || 'Document.pdf';
6496
+ iconName = 'FileText';
6497
+ }
6498
+ else {
6499
+ label = url.hostname.replace(/^www\./, '');
6500
+ }
6501
+ }
6502
+ catch (e) {
6503
+ // Invalid URL, treat as text
6504
+ }
6505
+ }
6506
+ else {
6507
+ // Text content - take first few words
6508
+ const words = content.split(/\s+/);
6509
+ if (words.length > 4) {
6510
+ label = words.slice(0, 4).join(' ') + '...';
6511
+ }
6512
+ }
6513
+ capabilities.push({
6514
+ type: 'knowledge',
6515
+ label,
6516
+ iconName,
6517
+ });
6518
+ continue;
6519
+ }
6305
6520
  if (commitment.type === 'META LINK') {
6306
6521
  const linkValue = spaceTrim$2(commitment.content);
6307
6522
  links.push(linkValue);
@@ -6312,6 +6527,10 @@ function parseAgentSource(agentSource) {
6312
6527
  meta.image = spaceTrim$2(commitment.content);
6313
6528
  continue;
6314
6529
  }
6530
+ if (commitment.type === 'META DESCRIPTION') {
6531
+ meta.description = spaceTrim$2(commitment.content);
6532
+ continue;
6533
+ }
6315
6534
  if (commitment.type === 'META COLOR') {
6316
6535
  meta.color = normalizeSeparator(commitment.content);
6317
6536
  continue;
@@ -6348,6 +6567,7 @@ function parseAgentSource(agentSource) {
6348
6567
  meta,
6349
6568
  links,
6350
6569
  parameters,
6570
+ capabilities,
6351
6571
  };
6352
6572
  }
6353
6573
  /**