@promptbook/wizard 0.112.0-56 → 0.112.0-58

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 (37) hide show
  1. package/esm/index.es.js +1068 -1083
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/ParsedAgentSourceWithCommitments.d.ts +7 -0
  4. package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/applyCommitmentsToAgentModelRequirements.d.ts +14 -0
  5. package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.d.ts +14 -0
  6. package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/filterCommitmentsForAgentModelRequirements.d.ts +10 -0
  7. package/esm/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/materializeInlineKnowledgeSources.d.ts +12 -0
  8. package/esm/src/book-2.0/agent-source/parseAgentSource/ParseAgentSourceState.d.ts +10 -0
  9. package/esm/src/book-2.0/agent-source/parseAgentSource/ParsedAgentProfile.d.ts +7 -0
  10. package/esm/src/book-2.0/agent-source/parseAgentSource/applyMetaCommitment.d.ts +8 -0
  11. package/esm/src/book-2.0/agent-source/parseAgentSource/consumeConversationSampleCommitment.d.ts +8 -0
  12. package/esm/src/book-2.0/agent-source/parseAgentSource/createCapabilitiesFromCommitment.d.ts +9 -0
  13. package/esm/src/book-2.0/agent-source/parseAgentSource/ensureMetaFullname.d.ts +7 -0
  14. package/esm/src/book-2.0/agent-source/parseAgentSource/extractAgentProfileText.d.ts +8 -0
  15. package/esm/src/book-2.0/agent-source/parseAgentSource/extractInitialMessage.d.ts +7 -0
  16. package/esm/src/book-2.0/agent-source/parseAgentSource/extractParsedAgentProfile.d.ts +8 -0
  17. package/esm/src/types/LlmToolDefinition.d.ts +17 -7
  18. package/esm/src/version.d.ts +1 -1
  19. package/package.json +2 -2
  20. package/umd/index.umd.js +1068 -1083
  21. package/umd/index.umd.js.map +1 -1
  22. package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/ParsedAgentSourceWithCommitments.d.ts +7 -0
  23. package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/applyCommitmentsToAgentModelRequirements.d.ts +14 -0
  24. package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/augmentAgentModelRequirementsFromSource.d.ts +14 -0
  25. package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/filterCommitmentsForAgentModelRequirements.d.ts +10 -0
  26. package/umd/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments/materializeInlineKnowledgeSources.d.ts +12 -0
  27. package/umd/src/book-2.0/agent-source/parseAgentSource/ParseAgentSourceState.d.ts +10 -0
  28. package/umd/src/book-2.0/agent-source/parseAgentSource/ParsedAgentProfile.d.ts +7 -0
  29. package/umd/src/book-2.0/agent-source/parseAgentSource/applyMetaCommitment.d.ts +8 -0
  30. package/umd/src/book-2.0/agent-source/parseAgentSource/consumeConversationSampleCommitment.d.ts +8 -0
  31. package/umd/src/book-2.0/agent-source/parseAgentSource/createCapabilitiesFromCommitment.d.ts +9 -0
  32. package/umd/src/book-2.0/agent-source/parseAgentSource/ensureMetaFullname.d.ts +7 -0
  33. package/umd/src/book-2.0/agent-source/parseAgentSource/extractAgentProfileText.d.ts +8 -0
  34. package/umd/src/book-2.0/agent-source/parseAgentSource/extractInitialMessage.d.ts +7 -0
  35. package/umd/src/book-2.0/agent-source/parseAgentSource/extractParsedAgentProfile.d.ts +8 -0
  36. package/umd/src/types/LlmToolDefinition.d.ts +17 -7
  37. package/umd/src/version.d.ts +1 -1
package/esm/index.es.js CHANGED
@@ -38,7 +38,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
38
38
  * @generated
39
39
  * @see https://github.com/webgptorg/promptbook
40
40
  */
41
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-56';
41
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-58';
42
42
  /**
43
43
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
44
44
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -19405,6 +19405,186 @@ function createBasicAgentModelRequirements(agentName) {
19405
19405
  }
19406
19406
  // TODO: [🐤] Deduplicate `AgentModelRequirements` and `ModelRequirements` model requirements
19407
19407
 
19408
+ /**
19409
+ * @@@
19410
+ *
19411
+ * @private utility for commitments
19412
+ */
19413
+ function formatOptionalInstructionBlock(label, content) {
19414
+ const trimmedContent = spaceTrim$1(content);
19415
+ if (!trimmedContent) {
19416
+ return '';
19417
+ }
19418
+ return spaceTrim$1((block) => `
19419
+ - ${label}:
19420
+ ${block(trimmedContent
19421
+ .split(/\r?\n/)
19422
+ .map((line) => `- ${line}`)
19423
+ .join('\n'))}
19424
+ `);
19425
+ }
19426
+
19427
+ /**
19428
+ * All `USE` commitment types currently participating in final system-message aggregation.
19429
+ *
19430
+ * @private internal constant for `aggregateUseCommitmentSystemMessages`
19431
+ */
19432
+ const AGGREGATED_USE_COMMITMENT_TYPES = [
19433
+ 'USE BROWSER',
19434
+ 'USE DEEPSEARCH',
19435
+ 'USE SEARCH ENGINE',
19436
+ 'USE TIME',
19437
+ ];
19438
+ /**
19439
+ * Prefix used for temporary in-system-message placeholders that preserve the first-occurrence position of aggregated `USE` sections.
19440
+ *
19441
+ * @private internal constant for `appendAggregatedUseCommitmentPlaceholder`
19442
+ */
19443
+ const AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX = '# AGGREGATED USE COMMITMENT: ';
19444
+ /**
19445
+ * Type guard for `USE` commitment types that are aggregated in the final system message.
19446
+ *
19447
+ * @param type - Commitment type to check.
19448
+ * @returns `true` when the commitment participates in `USE` system-message aggregation.
19449
+ *
19450
+ * @private internal utility of `aggregateUseCommitmentSystemMessages`
19451
+ */
19452
+ function isAggregatedUseCommitmentType(type) {
19453
+ return AGGREGATED_USE_COMMITMENT_TYPES.includes(type);
19454
+ }
19455
+ /**
19456
+ * Creates the placeholder token used to reserve the first-occurrence position of an aggregated `USE` system-message section.
19457
+ *
19458
+ * @param type - Aggregated `USE` commitment type.
19459
+ * @returns Single-line placeholder comment stored in the interim system message.
19460
+ *
19461
+ * @private internal utility of `appendAggregatedUseCommitmentPlaceholder`
19462
+ */
19463
+ function getAggregatedUseCommitmentPlaceholder(type) {
19464
+ return `${AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX}${type}`;
19465
+ }
19466
+ /**
19467
+ * Combines distinct additional instruction blocks in source order.
19468
+ *
19469
+ * @param additionalInstructions - Deduplicated instruction blocks collected from the agent source.
19470
+ * @returns Combined instruction text ready for `formatOptionalInstructionBlock`.
19471
+ *
19472
+ * @private internal utility of `createAggregatedUseCommitmentSystemMessage`
19473
+ */
19474
+ function combineAdditionalInstructions(additionalInstructions) {
19475
+ return additionalInstructions.join('\n');
19476
+ }
19477
+ /**
19478
+ * Creates the final aggregated system-message section for a supported `USE` commitment type.
19479
+ *
19480
+ * @param type - Aggregated `USE` commitment type.
19481
+ * @param additionalInstructions - Distinct additional instructions in source order.
19482
+ * @returns Final system-message block for the commitment type.
19483
+ *
19484
+ * @private internal utility of `aggregateUseCommitmentSystemMessages`
19485
+ */
19486
+ function createAggregatedUseCommitmentSystemMessage(type, additionalInstructions) {
19487
+ const combinedAdditionalInstructions = combineAdditionalInstructions(additionalInstructions);
19488
+ switch (type) {
19489
+ case 'USE TIME':
19490
+ return spaceTrim$1((block) => `
19491
+ Time and date context:
19492
+ - It is ${moment().format('MMMM YYYY')} now.
19493
+ - If you need more precise current time information, use the tool "get_current_time".
19494
+ ${block(formatOptionalInstructionBlock('Time instructions', combinedAdditionalInstructions))}
19495
+ `);
19496
+ case 'USE BROWSER':
19497
+ return spaceTrim$1((block) => `
19498
+ You have access to browser tools to fetch and access content from the internet.
19499
+ - Use "fetch_url_content" to retrieve content from specific URLs (webpages or documents) using scrapers.
19500
+ - Use "run_browser" for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
19501
+ When you need to know information from a specific website or document, use the fetch_url_content tool.
19502
+ ${block(formatOptionalInstructionBlock('Browser instructions', combinedAdditionalInstructions))}
19503
+ `);
19504
+ case 'USE SEARCH ENGINE':
19505
+ return spaceTrim$1((block) => `
19506
+ Tool:
19507
+ - You have access to the web search engine via the tool "web_search".
19508
+ - Use it to find up-to-date information or facts that you don't know.
19509
+ - When you need to know some information from the internet, use the tool provided to you.
19510
+ - Do not make up information when you can search for it.
19511
+ - Do not tell the user you cannot search for information, YOU CAN.
19512
+ ${block(formatOptionalInstructionBlock('Search instructions', combinedAdditionalInstructions))}
19513
+ `);
19514
+ case 'USE DEEPSEARCH':
19515
+ return spaceTrim$1((block) => `
19516
+ Tool:
19517
+ - You have access to DeepSearch via the tool "deep_search".
19518
+ - Use it for broader research tasks that need multi-step investigation, comparison, or synthesis across multiple sources.
19519
+ - Prefer it over quick search when the user asks for a well-grounded brief, report, or deeper investigation.
19520
+ - Do not pretend you cannot research current information when this tool is available.
19521
+ ${block(formatOptionalInstructionBlock('DeepSearch instructions', combinedAdditionalInstructions))}
19522
+ `);
19523
+ }
19524
+ }
19525
+ /**
19526
+ * Adds the placeholder for an aggregated `USE` system-message section only once, preserving the section position from the first occurrence.
19527
+ *
19528
+ * @param requirements - Current model requirements.
19529
+ * @param type - Aggregated `USE` commitment type being applied.
19530
+ * @returns Requirements with the placeholder inserted when it was not already present.
19531
+ *
19532
+ * @private internal utility of `USE` commitments
19533
+ */
19534
+ function appendAggregatedUseCommitmentPlaceholder(requirements, type) {
19535
+ const placeholder = getAggregatedUseCommitmentPlaceholder(type);
19536
+ if (requirements.systemMessage.includes(placeholder)) {
19537
+ return requirements;
19538
+ }
19539
+ const systemMessage = requirements.systemMessage.trim()
19540
+ ? `${requirements.systemMessage}\n\n${placeholder}`
19541
+ : placeholder;
19542
+ return {
19543
+ ...requirements,
19544
+ systemMessage,
19545
+ };
19546
+ }
19547
+ /**
19548
+ * Replaces temporary `USE` placeholders with one aggregated system-message block per commitment type.
19549
+ *
19550
+ * Distinct additional-instruction blocks are merged in stable source order while the hard-coded section is emitted only once.
19551
+ *
19552
+ * @param requirements - Model requirements produced by commitment-by-commitment application.
19553
+ * @param commitments - Filtered commitments in their original source order.
19554
+ * @returns Requirements with aggregated `USE` system-message sections.
19555
+ *
19556
+ * @private internal utility of `createAgentModelRequirementsWithCommitments`
19557
+ */
19558
+ function aggregateUseCommitmentSystemMessages(requirements, commitments) {
19559
+ const additionalInstructionsByType = new Map();
19560
+ for (const commitment of commitments) {
19561
+ if (!isAggregatedUseCommitmentType(commitment.type)) {
19562
+ continue;
19563
+ }
19564
+ let additionalInstructions = additionalInstructionsByType.get(commitment.type);
19565
+ if (!additionalInstructions) {
19566
+ additionalInstructions = [];
19567
+ additionalInstructionsByType.set(commitment.type, additionalInstructions);
19568
+ }
19569
+ const normalizedContent = spaceTrim$1(commitment.content);
19570
+ if (normalizedContent && !additionalInstructions.includes(normalizedContent)) {
19571
+ additionalInstructions.push(normalizedContent);
19572
+ }
19573
+ }
19574
+ let systemMessage = requirements.systemMessage;
19575
+ for (const [type, additionalInstructions] of additionalInstructionsByType) {
19576
+ const placeholder = getAggregatedUseCommitmentPlaceholder(type);
19577
+ if (!systemMessage.includes(placeholder)) {
19578
+ continue;
19579
+ }
19580
+ systemMessage = systemMessage.replace(placeholder, createAggregatedUseCommitmentSystemMessage(type, additionalInstructions));
19581
+ }
19582
+ return {
19583
+ ...requirements,
19584
+ systemMessage,
19585
+ };
19586
+ }
19587
+
19408
19588
  /**
19409
19589
  * Generates a regex pattern to match a specific commitment
19410
19590
  *
@@ -20723,25 +20903,6 @@ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
20723
20903
  }
20724
20904
  // Note: [💞] Ignore a discrepancy between file name and entity name
20725
20905
 
20726
- /**
20727
- * @@@
20728
- *
20729
- * @private utility for commitments
20730
- */
20731
- function formatOptionalInstructionBlock(label, content) {
20732
- const trimmedContent = spaceTrim$1(content);
20733
- if (!trimmedContent) {
20734
- return '';
20735
- }
20736
- return spaceTrim$1((block) => `
20737
- - ${label}:
20738
- ${block(trimmedContent
20739
- .split(/\r?\n/)
20740
- .map((line) => `- ${line}`)
20741
- .join('\n'))}
20742
- `);
20743
- }
20744
-
20745
20906
  /**
20746
20907
  * Names of tools used by the MEMORY commitment.
20747
20908
  *
@@ -27564,167 +27725,6 @@ class TemplateCommitmentDefinition extends BaseCommitmentDefinition {
27564
27725
  }
27565
27726
  // Note: [💞] Ignore a discrepancy between file name and entity name
27566
27727
 
27567
- /**
27568
- * All `USE` commitment types currently participating in final system-message aggregation.
27569
- *
27570
- * @private internal constant for `aggregateUseCommitmentSystemMessages`
27571
- */
27572
- const AGGREGATED_USE_COMMITMENT_TYPES = [
27573
- 'USE BROWSER',
27574
- 'USE DEEPSEARCH',
27575
- 'USE SEARCH ENGINE',
27576
- 'USE TIME',
27577
- ];
27578
- /**
27579
- * Prefix used for temporary in-system-message placeholders that preserve the first-occurrence position of aggregated `USE` sections.
27580
- *
27581
- * @private internal constant for `appendAggregatedUseCommitmentPlaceholder`
27582
- */
27583
- const AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX = '# AGGREGATED USE COMMITMENT: ';
27584
- /**
27585
- * Type guard for `USE` commitment types that are aggregated in the final system message.
27586
- *
27587
- * @param type - Commitment type to check.
27588
- * @returns `true` when the commitment participates in `USE` system-message aggregation.
27589
- *
27590
- * @private internal utility of `aggregateUseCommitmentSystemMessages`
27591
- */
27592
- function isAggregatedUseCommitmentType(type) {
27593
- return AGGREGATED_USE_COMMITMENT_TYPES.includes(type);
27594
- }
27595
- /**
27596
- * Creates the placeholder token used to reserve the first-occurrence position of an aggregated `USE` system-message section.
27597
- *
27598
- * @param type - Aggregated `USE` commitment type.
27599
- * @returns Single-line placeholder comment stored in the interim system message.
27600
- *
27601
- * @private internal utility of `appendAggregatedUseCommitmentPlaceholder`
27602
- */
27603
- function getAggregatedUseCommitmentPlaceholder(type) {
27604
- return `${AGGREGATED_USE_COMMITMENT_PLACEHOLDER_PREFIX}${type}`;
27605
- }
27606
- /**
27607
- * Combines distinct additional instruction blocks in source order.
27608
- *
27609
- * @param additionalInstructions - Deduplicated instruction blocks collected from the agent source.
27610
- * @returns Combined instruction text ready for `formatOptionalInstructionBlock`.
27611
- *
27612
- * @private internal utility of `createAggregatedUseCommitmentSystemMessage`
27613
- */
27614
- function combineAdditionalInstructions(additionalInstructions) {
27615
- return additionalInstructions.join('\n');
27616
- }
27617
- /**
27618
- * Creates the final aggregated system-message section for a supported `USE` commitment type.
27619
- *
27620
- * @param type - Aggregated `USE` commitment type.
27621
- * @param additionalInstructions - Distinct additional instructions in source order.
27622
- * @returns Final system-message block for the commitment type.
27623
- *
27624
- * @private internal utility of `aggregateUseCommitmentSystemMessages`
27625
- */
27626
- function createAggregatedUseCommitmentSystemMessage(type, additionalInstructions) {
27627
- const combinedAdditionalInstructions = combineAdditionalInstructions(additionalInstructions);
27628
- switch (type) {
27629
- case 'USE TIME':
27630
- return spaceTrim$1((block) => `
27631
- Time and date context:
27632
- - It is ${moment().format('MMMM YYYY')} now.
27633
- - If you need more precise current time information, use the tool "get_current_time".
27634
- ${block(formatOptionalInstructionBlock('Time instructions', combinedAdditionalInstructions))}
27635
- `);
27636
- case 'USE BROWSER':
27637
- return spaceTrim$1((block) => `
27638
- You have access to browser tools to fetch and access content from the internet.
27639
- - Use "fetch_url_content" to retrieve content from specific URLs (webpages or documents) using scrapers.
27640
- - Use "run_browser" for real interactive browser automation (navigation, clicks, typing, waiting, scrolling).
27641
- When you need to know information from a specific website or document, use the fetch_url_content tool.
27642
- ${block(formatOptionalInstructionBlock('Browser instructions', combinedAdditionalInstructions))}
27643
- `);
27644
- case 'USE SEARCH ENGINE':
27645
- return spaceTrim$1((block) => `
27646
- Tool:
27647
- - You have access to the web search engine via the tool "web_search".
27648
- - Use it to find up-to-date information or facts that you don't know.
27649
- - When you need to know some information from the internet, use the tool provided to you.
27650
- - Do not make up information when you can search for it.
27651
- - Do not tell the user you cannot search for information, YOU CAN.
27652
- ${block(formatOptionalInstructionBlock('Search instructions', combinedAdditionalInstructions))}
27653
- `);
27654
- case 'USE DEEPSEARCH':
27655
- return spaceTrim$1((block) => `
27656
- Tool:
27657
- - You have access to DeepSearch via the tool "deep_search".
27658
- - Use it for broader research tasks that need multi-step investigation, comparison, or synthesis across multiple sources.
27659
- - Prefer it over quick search when the user asks for a well-grounded brief, report, or deeper investigation.
27660
- - Do not pretend you cannot research current information when this tool is available.
27661
- ${block(formatOptionalInstructionBlock('DeepSearch instructions', combinedAdditionalInstructions))}
27662
- `);
27663
- }
27664
- }
27665
- /**
27666
- * Adds the placeholder for an aggregated `USE` system-message section only once, preserving the section position from the first occurrence.
27667
- *
27668
- * @param requirements - Current model requirements.
27669
- * @param type - Aggregated `USE` commitment type being applied.
27670
- * @returns Requirements with the placeholder inserted when it was not already present.
27671
- *
27672
- * @private internal utility of `USE` commitments
27673
- */
27674
- function appendAggregatedUseCommitmentPlaceholder(requirements, type) {
27675
- const placeholder = getAggregatedUseCommitmentPlaceholder(type);
27676
- if (requirements.systemMessage.includes(placeholder)) {
27677
- return requirements;
27678
- }
27679
- const systemMessage = requirements.systemMessage.trim()
27680
- ? `${requirements.systemMessage}\n\n${placeholder}`
27681
- : placeholder;
27682
- return {
27683
- ...requirements,
27684
- systemMessage,
27685
- };
27686
- }
27687
- /**
27688
- * Replaces temporary `USE` placeholders with one aggregated system-message block per commitment type.
27689
- *
27690
- * Distinct additional-instruction blocks are merged in stable source order while the hard-coded section is emitted only once.
27691
- *
27692
- * @param requirements - Model requirements produced by commitment-by-commitment application.
27693
- * @param commitments - Filtered commitments in their original source order.
27694
- * @returns Requirements with aggregated `USE` system-message sections.
27695
- *
27696
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
27697
- */
27698
- function aggregateUseCommitmentSystemMessages(requirements, commitments) {
27699
- const additionalInstructionsByType = new Map();
27700
- for (const commitment of commitments) {
27701
- if (!isAggregatedUseCommitmentType(commitment.type)) {
27702
- continue;
27703
- }
27704
- let additionalInstructions = additionalInstructionsByType.get(commitment.type);
27705
- if (!additionalInstructions) {
27706
- additionalInstructions = [];
27707
- additionalInstructionsByType.set(commitment.type, additionalInstructions);
27708
- }
27709
- const normalizedContent = spaceTrim$1(commitment.content);
27710
- if (normalizedContent && !additionalInstructions.includes(normalizedContent)) {
27711
- additionalInstructions.push(normalizedContent);
27712
- }
27713
- }
27714
- let systemMessage = requirements.systemMessage;
27715
- for (const [type, additionalInstructions] of additionalInstructionsByType) {
27716
- const placeholder = getAggregatedUseCommitmentPlaceholder(type);
27717
- if (!systemMessage.includes(placeholder)) {
27718
- continue;
27719
- }
27720
- systemMessage = systemMessage.replace(placeholder, createAggregatedUseCommitmentSystemMessage(type, additionalInstructions));
27721
- }
27722
- return {
27723
- ...requirements,
27724
- systemMessage,
27725
- };
27726
- }
27727
-
27728
27728
  /**
27729
27729
  * Client-side safe wrapper for fetching URL content
27730
27730
  *
@@ -28768,6 +28768,44 @@ function mapGoogleCalendarEvent(event) {
28768
28768
  * @private constant of createUseCalendarTools
28769
28769
  */
28770
28770
  const CALENDAR_URL_PARAMETER_DESCRIPTION = 'Google Calendar URL configured by USE CALENDAR (for example "https://calendar.google.com/...").';
28771
+ /**
28772
+ * Shared schema for string arrays used by USE CALENDAR tools.
28773
+ *
28774
+ * @private constant of createUseCalendarTools
28775
+ */
28776
+ const STRING_ARRAY_ITEMS_SCHEMA = {
28777
+ type: 'string',
28778
+ };
28779
+ /**
28780
+ * Shared schema for integer arrays used by USE CALENDAR tools.
28781
+ *
28782
+ * @private constant of createUseCalendarTools
28783
+ */
28784
+ const INTEGER_ARRAY_ITEMS_SCHEMA = {
28785
+ type: 'integer',
28786
+ };
28787
+ /**
28788
+ * Shared `sendUpdates` schema used by USE CALENDAR tools.
28789
+ *
28790
+ * @private constant of createUseCalendarTools
28791
+ */
28792
+ const SEND_UPDATES_PARAMETER_SCHEMA = {
28793
+ type: 'string',
28794
+ description: 'Guest update policy ("all", "externalOnly", "none").',
28795
+ enum: ['all', 'externalOnly', 'none'],
28796
+ };
28797
+ /**
28798
+ * Creates an array parameter schema with explicit item definition so OpenAI accepts it.
28799
+ *
28800
+ * @private function of createUseCalendarTools
28801
+ */
28802
+ function createArrayParameterSchema(description, items) {
28803
+ return {
28804
+ type: 'array',
28805
+ description,
28806
+ items,
28807
+ };
28808
+ }
28771
28809
  /**
28772
28810
  * Adds USE CALENDAR tool definitions while keeping already registered tools untouched.
28773
28811
  *
@@ -28874,18 +28912,9 @@ function createUseCalendarTools(existingTools) {
28874
28912
  type: 'string',
28875
28913
  description: 'Optional timezone for datetime values.',
28876
28914
  },
28877
- attendees: {
28878
- type: 'array',
28879
- description: 'Optional guest email list.',
28880
- },
28881
- reminderMinutes: {
28882
- type: 'array',
28883
- description: 'Optional popup reminder minute offsets.',
28884
- },
28885
- sendUpdates: {
28886
- type: 'string',
28887
- description: 'Guest update policy ("all", "externalOnly", "none").',
28888
- },
28915
+ attendees: createArrayParameterSchema('Optional guest email list.', STRING_ARRAY_ITEMS_SCHEMA),
28916
+ reminderMinutes: createArrayParameterSchema('Optional popup reminder minute offsets.', INTEGER_ARRAY_ITEMS_SCHEMA),
28917
+ sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
28889
28918
  },
28890
28919
  required: ['summary', 'start', 'end'],
28891
28920
  },
@@ -28928,18 +28957,9 @@ function createUseCalendarTools(existingTools) {
28928
28957
  type: 'string',
28929
28958
  description: 'Optional timezone for datetime values.',
28930
28959
  },
28931
- attendees: {
28932
- type: 'array',
28933
- description: 'Optional replacement guest email list.',
28934
- },
28935
- reminderMinutes: {
28936
- type: 'array',
28937
- description: 'Optional replacement popup reminder minute offsets.',
28938
- },
28939
- sendUpdates: {
28940
- type: 'string',
28941
- description: 'Guest update policy ("all", "externalOnly", "none").',
28942
- },
28960
+ attendees: createArrayParameterSchema('Optional replacement guest email list.', STRING_ARRAY_ITEMS_SCHEMA),
28961
+ reminderMinutes: createArrayParameterSchema('Optional replacement popup reminder minute offsets.', INTEGER_ARRAY_ITEMS_SCHEMA),
28962
+ sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
28943
28963
  },
28944
28964
  required: ['eventId'],
28945
28965
  },
@@ -28958,10 +28978,7 @@ function createUseCalendarTools(existingTools) {
28958
28978
  type: 'string',
28959
28979
  description: 'Google Calendar event id.',
28960
28980
  },
28961
- sendUpdates: {
28962
- type: 'string',
28963
- description: 'Guest update policy ("all", "externalOnly", "none").',
28964
- },
28981
+ sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
28965
28982
  },
28966
28983
  required: ['eventId'],
28967
28984
  },
@@ -28980,14 +28997,8 @@ function createUseCalendarTools(existingTools) {
28980
28997
  type: 'string',
28981
28998
  description: 'Google Calendar event id.',
28982
28999
  },
28983
- guests: {
28984
- type: 'array',
28985
- description: 'Guest email list to add to the event.',
28986
- },
28987
- sendUpdates: {
28988
- type: 'string',
28989
- description: 'Guest update policy ("all", "externalOnly", "none").',
28990
- },
29000
+ guests: createArrayParameterSchema('Guest email list to add to the event.', STRING_ARRAY_ITEMS_SCHEMA),
29001
+ sendUpdates: SEND_UPDATES_PARAMETER_SCHEMA,
28991
29002
  },
28992
29003
  required: ['eventId', 'guests'],
28993
29004
  },
@@ -33575,6 +33586,176 @@ function getCommitmentDefinition(type) {
33575
33586
  return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
33576
33587
  }
33577
33588
 
33589
+ /**
33590
+ * Commitment types whose content may contain compact agent references that must be resolved before applying the commitment.
33591
+ *
33592
+ * @private internal constant of `applyCommitmentsToAgentModelRequirements`
33593
+ */
33594
+ const COMMITMENTS_WITH_AGENT_REFERENCES = new Set(['FROM', 'IMPORT', 'IMPORTS', 'TEAM']);
33595
+ /**
33596
+ * Applies parsed commitments one by one while keeping the per-commitment steps focused and easy to follow.
33597
+ *
33598
+ * @param requirements - Current requirements snapshot.
33599
+ * @param commitments - Commitments already filtered for DELETE-like invalidations.
33600
+ * @param options - Optional reference and teammate resolvers.
33601
+ * @returns Requirements after all applicable commitments are processed.
33602
+ *
33603
+ * @private function of `createAgentModelRequirementsWithCommitments`
33604
+ */
33605
+ async function applyCommitmentsToAgentModelRequirements(requirements, commitments, options) {
33606
+ for (const [index, commitment] of commitments.entries()) {
33607
+ if (shouldSkipCommitmentApplication(commitment, index, commitments.length)) {
33608
+ continue;
33609
+ }
33610
+ const commitmentContent = await resolveCommitmentContent(commitment, options === null || options === void 0 ? void 0 : options.agentReferenceResolver);
33611
+ requirements = await preResolveTeammateProfilesForTeamCommitment(requirements, commitment, commitmentContent, options);
33612
+ requirements = applyCommitmentDefinitionSafely(requirements, commitment, commitmentContent);
33613
+ }
33614
+ return requirements;
33615
+ }
33616
+ /**
33617
+ * Resolves compact agent references for commitment types that support them.
33618
+ *
33619
+ * @param commitment - Commitment currently being applied.
33620
+ * @param agentReferenceResolver - Optional resolver for compact agent references.
33621
+ * @returns Original or resolved commitment content.
33622
+ *
33623
+ * @private internal utility of `applyCommitmentsToAgentModelRequirements`
33624
+ */
33625
+ async function resolveCommitmentContent(commitment, agentReferenceResolver) {
33626
+ if (!agentReferenceResolver || !isAgentReferenceCommitment(commitment.type)) {
33627
+ return commitment.content;
33628
+ }
33629
+ try {
33630
+ return await agentReferenceResolver.resolveCommitmentContent(commitment.type, commitment.content);
33631
+ }
33632
+ catch (error) {
33633
+ console.warn(`Failed to resolve commitment references for ${commitment.type}, falling back to safe defaults:`, error);
33634
+ return getSafeReferenceCommitmentFallback(commitment.type, commitment.content);
33635
+ }
33636
+ }
33637
+ /**
33638
+ * Returns a safe fallback content when a resolver fails to transform a reference commitment.
33639
+ *
33640
+ * @param commitmentType - Commitment being resolved.
33641
+ * @param originalContent - Original unresolved commitment content.
33642
+ * @returns Fallback content that keeps requirement creation resilient.
33643
+ *
33644
+ * @private internal utility of `applyCommitmentsToAgentModelRequirements`
33645
+ */
33646
+ function getSafeReferenceCommitmentFallback(commitmentType, originalContent) {
33647
+ if (commitmentType === 'FROM') {
33648
+ return 'VOID';
33649
+ }
33650
+ if (commitmentType === 'IMPORT' || commitmentType === 'IMPORTS' || commitmentType === 'TEAM') {
33651
+ return '';
33652
+ }
33653
+ return originalContent;
33654
+ }
33655
+ /**
33656
+ * Checks whether the commitment content may need agent-reference resolution before application.
33657
+ *
33658
+ * @param commitmentType - Commitment type to check.
33659
+ * @returns `true` when the commitment can contain compact agent references.
33660
+ *
33661
+ * @private internal utility of `resolveCommitmentContent`
33662
+ */
33663
+ function isAgentReferenceCommitment(commitmentType) {
33664
+ return COMMITMENTS_WITH_AGENT_REFERENCES.has(commitmentType);
33665
+ }
33666
+ /**
33667
+ * Determines whether a commitment should be skipped before resolution or application.
33668
+ *
33669
+ * @param commitment - Commitment under consideration.
33670
+ * @param commitmentIndex - Zero-based position among filtered commitments.
33671
+ * @param commitmentCount - Total number of filtered commitments.
33672
+ * @returns `true` when the commitment should not be applied.
33673
+ *
33674
+ * @private internal utility of `applyCommitmentsToAgentModelRequirements`
33675
+ */
33676
+ function shouldSkipCommitmentApplication(commitment, commitmentIndex, commitmentCount) {
33677
+ return commitment.type === 'CLOSED' && commitmentIndex !== commitmentCount - 1;
33678
+ }
33679
+ /**
33680
+ * Pre-resolves teammate profiles for TEAM commitments so the TEAM commitment definition can reuse richer metadata.
33681
+ *
33682
+ * @param requirements - Current requirements snapshot.
33683
+ * @param commitment - Commitment currently being prepared.
33684
+ * @param commitmentContent - Already resolved TEAM commitment content.
33685
+ * @param options - Optional teammate profile resolvers.
33686
+ * @returns Requirements with pre-resolved teammate profiles stored in metadata when possible.
33687
+ *
33688
+ * @private internal utility of `applyCommitmentsToAgentModelRequirements`
33689
+ */
33690
+ async function preResolveTeammateProfilesForTeamCommitment(requirements, commitment, commitmentContent, options) {
33691
+ var _a;
33692
+ const profileResolver = (_a = options === null || options === void 0 ? void 0 : options.teammateProfileResolver) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.agentReferenceResolver;
33693
+ if (commitment.type !== 'TEAM' || !(profileResolver === null || profileResolver === void 0 ? void 0 : profileResolver.resolveTeammateProfile)) {
33694
+ return requirements;
33695
+ }
33696
+ try {
33697
+ const parsedTeammates = parseTeamCommitmentContent(commitmentContent, { strict: false });
33698
+ const preResolvedTeammateProfiles = clonePreResolvedTeammateProfiles(requirements._metadata);
33699
+ for (const teammate of parsedTeammates) {
33700
+ if (preResolvedTeammateProfiles[teammate.url]) {
33701
+ continue;
33702
+ }
33703
+ const profile = await profileResolver.resolveTeammateProfile(teammate.url);
33704
+ if (profile) {
33705
+ preResolvedTeammateProfiles[teammate.url] = profile;
33706
+ }
33707
+ }
33708
+ return {
33709
+ ...requirements,
33710
+ _metadata: {
33711
+ ...requirements._metadata,
33712
+ preResolvedTeammateProfiles,
33713
+ },
33714
+ };
33715
+ }
33716
+ catch (error) {
33717
+ console.warn('Failed to pre-resolve teammate profiles for TEAM commitment:', error);
33718
+ return requirements;
33719
+ }
33720
+ }
33721
+ /**
33722
+ * Clones the metadata bucket used to cache teammate profiles resolved ahead of TEAM commitment application.
33723
+ *
33724
+ * @param metadata - Current requirements metadata.
33725
+ * @returns Mutable copy of the cached teammate profile map.
33726
+ *
33727
+ * @private internal utility of `preResolveTeammateProfilesForTeamCommitment`
33728
+ */
33729
+ function clonePreResolvedTeammateProfiles(metadata) {
33730
+ var _a;
33731
+ return {
33732
+ ...((_a = metadata === null || metadata === void 0 ? void 0 : metadata.preResolvedTeammateProfiles) !== null && _a !== void 0 ? _a : {}),
33733
+ };
33734
+ }
33735
+ /**
33736
+ * Applies the registered commitment definition while isolating the failure handling from the main loop.
33737
+ *
33738
+ * @param requirements - Current requirements snapshot.
33739
+ * @param commitment - Commitment whose definition should be applied.
33740
+ * @param commitmentContent - Final content passed into the definition.
33741
+ * @returns Updated requirements, or the original requirements when the commitment fails.
33742
+ *
33743
+ * @private internal utility of `applyCommitmentsToAgentModelRequirements`
33744
+ */
33745
+ function applyCommitmentDefinitionSafely(requirements, commitment, commitmentContent) {
33746
+ const definition = getCommitmentDefinition(commitment.type);
33747
+ if (!definition) {
33748
+ return requirements;
33749
+ }
33750
+ try {
33751
+ return definition.applyToAgentModelRequirements(requirements, commitmentContent);
33752
+ }
33753
+ catch (error) {
33754
+ console.warn(`Failed to apply commitment ${commitment.type}:`, error);
33755
+ return requirements;
33756
+ }
33757
+ }
33758
+
33578
33759
  /**
33579
33760
  * Consumes the agent-name prelude from raw source.
33580
33761
  *
@@ -33842,6 +34023,285 @@ const $fileImportPlugins = [
33842
34023
  TextFileImportPlugin,
33843
34024
  ];
33844
34025
 
34026
+ /**
34027
+ * Regex pattern matching markdown horizontal lines that should not be copied into the final system message.
34028
+ *
34029
+ * @private internal constant of `augmentAgentModelRequirementsFromSource`
34030
+ */
34031
+ const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
34032
+ /**
34033
+ * MIME type prefixes treated as binary and therefore not eligible for text import plugins.
34034
+ *
34035
+ * @private internal constant of `augmentAgentModelRequirementsFromSource`
34036
+ */
34037
+ const BINARY_MIME_TYPE_PREFIXES = [
34038
+ 'image/',
34039
+ 'video/',
34040
+ 'audio/',
34041
+ 'application/octet-stream',
34042
+ 'application/pdf',
34043
+ 'application/zip',
34044
+ ];
34045
+ /**
34046
+ * Adds source-derived sections after commitments have been applied.
34047
+ *
34048
+ * @param requirements - Requirements after commitment application and USE aggregation.
34049
+ * @param parseResult - Parsed source used to recover non-commitment prose and examples.
34050
+ * @param agentSource - Original source used to recover MCP server declarations.
34051
+ * @returns Requirements with source-derived sections appended.
34052
+ *
34053
+ * @private function of `createAgentModelRequirementsWithCommitments`
34054
+ */
34055
+ async function augmentAgentModelRequirementsFromSource(requirements, parseResult, agentSource) {
34056
+ requirements = await importReferencedFiles(requirements);
34057
+ requirements = appendMcpServers(requirements, agentSource);
34058
+ requirements = appendNonCommitmentContent(requirements, parseResult);
34059
+ return appendExampleInteractions(requirements, parseResult);
34060
+ }
34061
+ /**
34062
+ * Imports text files referenced by IMPORT commitments and appends their transformed content to the system message.
34063
+ *
34064
+ * @param requirements - Requirements possibly containing `importedFileUrls`.
34065
+ * @returns Requirements with imported file content appended to the system message.
34066
+ *
34067
+ * @private internal utility of `augmentAgentModelRequirementsFromSource`
34068
+ */
34069
+ async function importReferencedFiles(requirements) {
34070
+ const importedFileUrls = requirements.importedFileUrls;
34071
+ if (!importedFileUrls || importedFileUrls.length === 0) {
34072
+ return requirements;
34073
+ }
34074
+ for (const fileUrl of importedFileUrls) {
34075
+ try {
34076
+ const importedContent = await createImportedFileSystemMessage(fileUrl);
34077
+ requirements = appendSystemMessageSection(requirements, importedContent);
34078
+ }
34079
+ catch (error) {
34080
+ console.warn(`Failed to import file ${fileUrl}:`, error);
34081
+ }
34082
+ }
34083
+ return requirements;
34084
+ }
34085
+ /**
34086
+ * Loads, validates, and transforms one imported file into a system-message block.
34087
+ *
34088
+ * @param fileUrl - Remote URL or local path declared in an IMPORT commitment.
34089
+ * @returns Imported text ready to append to the system message.
34090
+ *
34091
+ * @private internal utility of `importReferencedFiles`
34092
+ */
34093
+ async function createImportedFileSystemMessage(fileUrl) {
34094
+ await mockedSecurityCheck(fileUrl);
34095
+ const { content, mimeType } = await readImportedFile(fileUrl);
34096
+ if (isBinaryMimeType(mimeType)) {
34097
+ throw new Error(`Importing binary files is not allowed: ${mimeType}`);
34098
+ }
34099
+ const plugin = $fileImportPlugins.find((fileImportPlugin) => fileImportPlugin.canImport(mimeType));
34100
+ if (!plugin) {
34101
+ throw new Error(`No import plugin found for MIME type: ${mimeType}`);
34102
+ }
34103
+ return plugin.import(content, mimeType);
34104
+ }
34105
+ /**
34106
+ * Reads one imported file and normalizes the MIME type expected by file import plugins.
34107
+ *
34108
+ * @param fileUrl - Remote URL or local path declared in an IMPORT commitment.
34109
+ * @returns Plain-text content together with a normalized MIME type.
34110
+ *
34111
+ * @private internal utility of `createImportedFileSystemMessage`
34112
+ */
34113
+ async function readImportedFile(fileUrl) {
34114
+ if (isValidUrl(fileUrl)) {
34115
+ const response = await promptbookFetch(fileUrl);
34116
+ if (!response.ok) {
34117
+ throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`);
34118
+ }
34119
+ return {
34120
+ content: await response.text(),
34121
+ mimeType: normalizeImportedMimeType(response.headers.get('Content-Type')),
34122
+ };
34123
+ }
34124
+ /*
34125
+ TODO: !!!! Commented out this case because we need to work in Browser-compatible mode in many packages, use passed `fs` instead
34126
+ } else if (isValidFilePath(fileUrl)) {
34127
+ // [x🟢x] This code is expected to run in Node environment if local files are used
34128
+ const fs = await import('fs/promises');
34129
+ content = await fs.readFile(fileUrl, 'utf-8');
34130
+ const extension = getFileExtension(fileUrl);
34131
+ mimeType = extensionToMimeType(extension as string);
34132
+ */
34133
+ throw new Error(`Invalid file URL or path: ${fileUrl}`);
34134
+ }
34135
+ /**
34136
+ * Normalizes MIME types returned by fetch so plugin lookup works on bare MIME values without charset suffixes.
34137
+ *
34138
+ * @param mimeType - Raw response MIME type header.
34139
+ * @returns Normalized MIME type fallbacking to `text/plain`.
34140
+ *
34141
+ * @private internal utility of `readImportedFile`
34142
+ */
34143
+ function normalizeImportedMimeType(mimeType) {
34144
+ return (mimeType || 'text/plain').split(';')[0].trim();
34145
+ }
34146
+ /**
34147
+ * Appends extracted MCP server identifiers from the original source.
34148
+ *
34149
+ * @param requirements - Current requirements snapshot.
34150
+ * @param agentSource - Original agent source used for MCP extraction.
34151
+ * @returns Requirements with `mcpServers` set when MCP commitments are present.
34152
+ *
34153
+ * @private internal utility of `augmentAgentModelRequirementsFromSource`
34154
+ */
34155
+ function appendMcpServers(requirements, agentSource) {
34156
+ const mcpServers = extractMcpServers(agentSource);
34157
+ if (mcpServers.length === 0) {
34158
+ return requirements;
34159
+ }
34160
+ return {
34161
+ ...requirements,
34162
+ mcpServers,
34163
+ };
34164
+ }
34165
+ /**
34166
+ * Appends non-commitment prose from the source after filtering out blank lines and markdown horizontal rules.
34167
+ *
34168
+ * @param requirements - Current requirements snapshot.
34169
+ * @param parseResult - Parsed source including non-commitment lines.
34170
+ * @returns Requirements with the remaining prose appended to the system message.
34171
+ *
34172
+ * @private internal utility of `augmentAgentModelRequirementsFromSource`
34173
+ */
34174
+ function appendNonCommitmentContent(requirements, parseResult) {
34175
+ const nonCommitmentContent = getNonCommitmentContent(parseResult);
34176
+ if (!nonCommitmentContent) {
34177
+ return requirements;
34178
+ }
34179
+ return appendSystemMessageSection(requirements, nonCommitmentContent);
34180
+ }
34181
+ /**
34182
+ * Collects plain-text lines that were not parsed as commitments and should still become part of the final system message.
34183
+ *
34184
+ * @param parseResult - Parsed source including non-commitment lines.
34185
+ * @returns Joined non-commitment content or an empty string when there is nothing to append.
34186
+ *
34187
+ * @private internal utility of `appendNonCommitmentContent`
34188
+ */
34189
+ function getNonCommitmentContent(parseResult) {
34190
+ return parseResult.nonCommitmentLines
34191
+ .filter((line, index) => index > 0 || !parseResult.agentName)
34192
+ .filter((line) => line.trim())
34193
+ .filter((line) => !isHorizontalLine(line))
34194
+ .join('\n')
34195
+ .trim();
34196
+ }
34197
+ /**
34198
+ * Checks whether a line is a markdown horizontal separator.
34199
+ *
34200
+ * @param line - Source line to inspect.
34201
+ * @returns `true` when the line is a thematic break.
34202
+ *
34203
+ * @private internal utility of `getNonCommitmentContent`
34204
+ */
34205
+ function isHorizontalLine(line) {
34206
+ return HORIZONTAL_LINE_PATTERN.test(line);
34207
+ }
34208
+ /**
34209
+ * Appends example interactions assembled from INITIAL MESSAGE and USER/AGENT sample commitments.
34210
+ *
34211
+ * @param requirements - Current requirements snapshot.
34212
+ * @param parseResult - Parsed source used to recover initial message content.
34213
+ * @returns Requirements with the example interaction block appended when examples exist.
34214
+ *
34215
+ * @private internal utility of `augmentAgentModelRequirementsFromSource`
34216
+ */
34217
+ function appendExampleInteractions(requirements, parseResult) {
34218
+ const exampleInteractionsContent = createExampleInteractionsContent(parseResult, requirements.samples);
34219
+ if (!exampleInteractionsContent) {
34220
+ return requirements;
34221
+ }
34222
+ return appendSystemMessageSection(requirements, exampleInteractionsContent);
34223
+ }
34224
+ /**
34225
+ * Creates the formatted example-interaction section appended to the final system message.
34226
+ *
34227
+ * @param parseResult - Parsed source used to recover the initial message commitment.
34228
+ * @param samples - Parsed USER/AGENT sample pairs already stored on requirements.
34229
+ * @returns Formatted example interaction block or `null` when no examples exist.
34230
+ *
34231
+ * @private internal utility of `appendExampleInteractions`
34232
+ */
34233
+ function createExampleInteractionsContent(parseResult, samples) {
34234
+ const examples = collectExampleInteractionLines(parseResult, samples);
34235
+ if (examples.length === 0) {
34236
+ return null;
34237
+ }
34238
+ return `Example interaction:\n\n${examples.join('\n\n')}`;
34239
+ }
34240
+ /**
34241
+ * Collects the individual lines used in the example interaction section.
34242
+ *
34243
+ * @param parseResult - Parsed source used to recover the initial message commitment.
34244
+ * @param samples - Parsed USER/AGENT sample pairs already stored on requirements.
34245
+ * @returns Individual example interaction snippets in output order.
34246
+ *
34247
+ * @private internal utility of `createExampleInteractionsContent`
34248
+ */
34249
+ function collectExampleInteractionLines(parseResult, samples) {
34250
+ var _a;
34251
+ const examples = [];
34252
+ const initialMessage = (_a = parseResult.commitments.find((commitment) => commitment.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
34253
+ if (initialMessage) {
34254
+ examples.push(`Agent: ${initialMessage}`);
34255
+ }
34256
+ if (samples && samples.length > 0) {
34257
+ for (const sample of samples) {
34258
+ examples.push(`User: ${sample.question}\nAgent: ${sample.answer}`);
34259
+ }
34260
+ }
34261
+ return examples;
34262
+ }
34263
+ /**
34264
+ * Appends a single system-message section using the same blank-line separation used throughout the original implementation.
34265
+ *
34266
+ * @param requirements - Current requirements snapshot.
34267
+ * @param section - Section content to append.
34268
+ * @returns Requirements with the additional system-message block appended.
34269
+ *
34270
+ * @private internal utility of `augmentAgentModelRequirementsFromSource`
34271
+ */
34272
+ function appendSystemMessageSection(requirements, section) {
34273
+ return {
34274
+ ...requirements,
34275
+ systemMessage: requirements.systemMessage + '\n\n' + section,
34276
+ };
34277
+ }
34278
+ /**
34279
+ * Mocked security check for imported files.
34280
+ *
34281
+ * @param urlOrPath - The URL or local path of the file to check.
34282
+ * @returns A promise that resolves if the file is considered safe.
34283
+ *
34284
+ * @private internal utility of `createImportedFileSystemMessage`
34285
+ */
34286
+ async function mockedSecurityCheck(urlOrPath) {
34287
+ // TODO: Implement proper security checks
34288
+ await new Promise((resolve) => setTimeout(resolve, 10));
34289
+ if (urlOrPath.includes('malicious')) {
34290
+ throw new Error(`Security check failed for: ${urlOrPath}`);
34291
+ }
34292
+ }
34293
+ /**
34294
+ * Checks whether the given MIME type belongs to a binary file.
34295
+ *
34296
+ * @param mimeType - The MIME type to check.
34297
+ * @returns `true` when the MIME type is treated as binary.
34298
+ *
34299
+ * @private internal utility of `createImportedFileSystemMessage`
34300
+ */
34301
+ function isBinaryMimeType(mimeType) {
34302
+ return BINARY_MIME_TYPE_PREFIXES.some((prefix) => mimeType.startsWith(prefix));
34303
+ }
34304
+
33845
34305
  /**
33846
34306
  * Parses parameters from text using both supported notations:
33847
34307
  * 1. @Parameter - single word parameter starting with @
@@ -33901,121 +34361,39 @@ function parseParameters(text) {
33901
34361
  return uniqueParameters;
33902
34362
  }
33903
34363
 
33904
- /**
33905
- * Removes single-hash comment lines (`# Comment`) from a system message
33906
- * This is used to clean up the final system message before sending it to the AI model
33907
- * while preserving the original content with comments in metadata
33908
- *
33909
- * @param systemMessage The system message that may contain comment lines
33910
- * @returns The system message with single-hash comment lines removed
33911
- *
33912
- * @private - TODO: [🧠] Maybe should be public?
33913
- */
33914
- function removeCommentsFromSystemMessage(systemMessage) {
33915
- if (!systemMessage) {
33916
- return systemMessage;
33917
- }
33918
- const lines = systemMessage.split(/\r?\n/);
33919
- const filteredLines = lines.filter((line) => {
33920
- const trimmedLine = line.trim();
33921
- // Remove only single-hash comment markers (`# Comment`) and keep markdown headings (`## Heading`).
33922
- return !/^#(?!#)\s/.test(trimmedLine);
33923
- });
33924
- return filteredLines.join('\n').trim();
33925
- }
33926
-
33927
- /**
33928
- * Commitment types whose content may contain compact agent references that must be resolved before applying the commitment.
33929
- *
33930
- * @private internal constant of `createAgentModelRequirementsWithCommitments`
33931
- */
33932
- const COMMITMENTS_WITH_AGENT_REFERENCES = new Set(['FROM', 'IMPORT', 'IMPORTS', 'TEAM']);
33933
34364
  /**
33934
34365
  * DELETE-like commitment types that invalidate earlier tagged commitments.
33935
34366
  *
33936
- * @private internal constant of `createAgentModelRequirementsWithCommitments`
34367
+ * @private internal constant of `filterCommitmentsForAgentModelRequirements`
33937
34368
  */
33938
34369
  const DELETE_COMMITMENT_TYPES = new Set(['DELETE', 'CANCEL', 'DISCARD', 'REMOVE']);
33939
34370
  /**
33940
34371
  * Commitments whose earlier occurrences are overwritten by the last occurrence in source order.
33941
34372
  *
33942
- * @private internal constant of `createAgentModelRequirementsWithCommitments`
34373
+ * @private internal constant of `filterCommitmentsForAgentModelRequirements`
33943
34374
  */
33944
34375
  const OVERWRITTEN_COMMITMENT_GROUP_BY_TYPE = new Map([
33945
34376
  ['GOAL', 'GOAL'],
33946
34377
  ['GOALS', 'GOAL'],
33947
34378
  ]);
33948
34379
  /**
33949
- * Regex pattern matching markdown horizontal lines that should not be copied into the final system message.
33950
- *
33951
- * @private internal constant of `createAgentModelRequirementsWithCommitments`
33952
- */
33953
- const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
33954
- /**
33955
- * MIME type prefixes treated as binary and therefore not eligible for text import plugins.
34380
+ * Applies the commitment filtering rules used before commitment definitions are executed.
33956
34381
  *
33957
- * @private internal constant of `createAgentModelRequirementsWithCommitments`
33958
- */
33959
- const BINARY_MIME_TYPE_PREFIXES = [
33960
- 'image/',
33961
- 'video/',
33962
- 'audio/',
33963
- 'application/octet-stream',
33964
- 'application/pdf',
33965
- 'application/zip',
33966
- ];
33967
- /**
33968
- * Returns a safe fallback content when a resolver fails to transform a reference commitment.
33969
- *
33970
- * @param commitmentType - Commitment being resolved.
33971
- * @param originalContent - Original unresolved commitment content.
33972
- * @returns Fallback content that keeps requirement creation resilient.
33973
- *
33974
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
33975
- */
33976
- function getSafeReferenceCommitmentFallback(commitmentType, originalContent) {
33977
- if (commitmentType === 'FROM') {
33978
- return 'VOID';
33979
- }
33980
- if (commitmentType === 'IMPORT' || commitmentType === 'IMPORTS' || commitmentType === 'TEAM') {
33981
- return '';
33982
- }
33983
- return originalContent;
33984
- }
33985
- /**
33986
- * Creates agent model requirements by parsing commitments, applying them in source order,
33987
- * and finalizing derived sections such as imports, example interactions, and inline knowledge uploads.
33988
- *
33989
- * @param agentSource - Agent source book to parse.
33990
- * @param modelName - Optional override for the agent model name.
33991
- * @param options - Additional options such as reference and teammate resolvers.
33992
- * @returns Fully prepared model requirements for the parsed agent source.
34382
+ * @param commitments - Parsed commitments in original source order.
34383
+ * @returns Commitments after DELETE-like invalidation and overwritten-goal filtering.
33993
34384
  *
33994
- * @private internal utility of `createAgentModelRequirements`
34385
+ * @private function of `createAgentModelRequirementsWithCommitments`
33995
34386
  */
33996
- async function createAgentModelRequirementsWithCommitments(agentSource, modelName, options) {
33997
- const parseResult = parseAgentSourceWithCommitments(agentSource);
33998
- const filteredCommitments = filterOverwrittenCommitments(filterDeletedCommitments(parseResult.commitments));
33999
- let requirements = createInitialAgentModelRequirements(parseResult.agentName, modelName);
34000
- requirements = await applyCommitmentsToRequirements(requirements, filteredCommitments, options);
34001
- requirements = aggregateUseCommitmentSystemMessages(requirements, filteredCommitments);
34002
- requirements = await importReferencedFiles(requirements);
34003
- requirements = appendMcpServers(requirements, agentSource);
34004
- requirements = appendNonCommitmentContent(requirements, parseResult);
34005
- requirements = appendExampleInteractions(requirements, parseResult);
34006
- requirements = await applyPendingInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
34007
- return finalizeRequirements(requirements);
34387
+ function filterCommitmentsForAgentModelRequirements(commitments) {
34388
+ return filterOverwrittenCommitments(filterDeletedCommitments(commitments));
34008
34389
  }
34009
34390
  /**
34010
34391
  * Removes earlier commitments that are overwritten by later commitments of the same semantic group.
34011
34392
  *
34012
- * This currently keeps only the last `GOAL` / `GOALS` commitment so inheritance rewrites
34013
- * and multi-goal sources expose one effective goal to the runtime.
34014
- *
34015
34393
  * @param commitments - Parsed commitments after DELETE-like filtering.
34016
34394
  * @returns Commitments with overwritten entries removed while preserving source order.
34017
34395
  *
34018
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34396
+ * @private internal utility of `filterCommitmentsForAgentModelRequirements`
34019
34397
  */
34020
34398
  function filterOverwrittenCommitments(commitments) {
34021
34399
  const seenOverwriteGroups = new Set();
@@ -34035,39 +34413,13 @@ function filterOverwrittenCommitments(commitments) {
34035
34413
  }
34036
34414
  return keptCommitments.reverse();
34037
34415
  }
34038
- /**
34039
- * Creates the initial requirements object with the parsed agent name stored in metadata and an optional model override.
34040
- *
34041
- * @param agentName - Parsed agent name from the source prelude.
34042
- * @param modelName - Optional explicit model name override.
34043
- * @returns Initial requirements before any commitment is applied.
34044
- *
34045
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34046
- */
34047
- function createInitialAgentModelRequirements(agentName, modelName) {
34048
- const initialRequirements = createBasicAgentModelRequirements(agentName);
34049
- const requirementsWithMetadata = {
34050
- ...initialRequirements,
34051
- _metadata: {
34052
- ...initialRequirements._metadata,
34053
- agentName,
34054
- },
34055
- };
34056
- if (!modelName) {
34057
- return requirementsWithMetadata;
34058
- }
34059
- return {
34060
- ...requirementsWithMetadata,
34061
- modelName,
34062
- };
34063
- }
34064
34416
  /**
34065
34417
  * Applies DELETE-like invalidation commitments and returns only commitments that should continue through the pipeline.
34066
34418
  *
34067
34419
  * @param commitments - Parsed commitments in original source order.
34068
34420
  * @returns Filtered commitments with earlier deleted items removed.
34069
34421
  *
34070
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34422
+ * @private internal utility of `filterCommitmentsForAgentModelRequirements`
34071
34423
  */
34072
34424
  function filterDeletedCommitments(commitments) {
34073
34425
  const filteredCommitments = [];
@@ -34115,590 +34467,469 @@ function getCommitmentParameterNames(content) {
34115
34467
  .map((parameter) => parameter.name.trim().toLowerCase())
34116
34468
  .filter(Boolean);
34117
34469
  }
34470
+
34118
34471
  /**
34119
- * Applies parsed commitments one by one while keeping the per-commitment steps focused and easy to follow.
34120
- *
34121
- * @param requirements - Current requirements snapshot.
34122
- * @param commitments - Commitments already filtered for DELETE-like invalidations.
34123
- * @param options - Optional reference and teammate resolvers.
34124
- * @returns Requirements after all applicable commitments are processed.
34125
- *
34126
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34127
- */
34128
- async function applyCommitmentsToRequirements(requirements, commitments, options) {
34129
- for (const [index, commitment] of commitments.entries()) {
34130
- if (shouldSkipCommitmentApplication(commitment, index, commitments.length)) {
34131
- continue;
34132
- }
34133
- const commitmentContent = await resolveCommitmentContent(commitment, options === null || options === void 0 ? void 0 : options.agentReferenceResolver);
34134
- requirements = await preResolveTeammateProfilesForTeamCommitment(requirements, commitment, commitmentContent, options);
34135
- requirements = applyCommitmentDefinitionSafely(requirements, commitment, commitmentContent);
34136
- }
34137
- return requirements;
34138
- }
34139
- /**
34140
- * Resolves compact agent references for commitment types that support them.
34141
- *
34142
- * @param commitment - Commitment currently being applied.
34143
- * @param agentReferenceResolver - Optional resolver for compact agent references.
34144
- * @returns Original or resolved commitment content.
34145
- *
34146
- * @private internal utility of `applyCommitmentsToRequirements`
34147
- */
34148
- async function resolveCommitmentContent(commitment, agentReferenceResolver) {
34149
- if (!agentReferenceResolver || !isAgentReferenceCommitment(commitment.type)) {
34150
- return commitment.content;
34151
- }
34152
- try {
34153
- return await agentReferenceResolver.resolveCommitmentContent(commitment.type, commitment.content);
34154
- }
34155
- catch (error) {
34156
- console.warn(`Failed to resolve commitment references for ${commitment.type}, falling back to safe defaults:`, error);
34157
- return getSafeReferenceCommitmentFallback(commitment.type, commitment.content);
34158
- }
34159
- }
34160
- /**
34161
- * Checks whether the commitment content may need agent-reference resolution before application.
34162
- *
34163
- * @param commitmentType - Commitment type to check.
34164
- * @returns `true` when the commitment can contain compact agent references.
34165
- *
34166
- * @private internal utility of `resolveCommitmentContent`
34167
- */
34168
- function isAgentReferenceCommitment(commitmentType) {
34169
- return COMMITMENTS_WITH_AGENT_REFERENCES.has(commitmentType);
34170
- }
34171
- /**
34172
- * Determines whether a commitment should be skipped before resolution or application.
34173
- *
34174
- * @param commitment - Commitment under consideration.
34175
- * @param commitmentIndex - Zero-based position among filtered commitments.
34176
- * @param commitmentCount - Total number of filtered commitments.
34177
- * @returns `true` when the commitment should not be applied.
34178
- *
34179
- * @private internal utility of `applyCommitmentsToRequirements`
34180
- */
34181
- function shouldSkipCommitmentApplication(commitment, commitmentIndex, commitmentCount) {
34182
- return commitment.type === 'CLOSED' && commitmentIndex !== commitmentCount - 1;
34183
- }
34184
- /**
34185
- * Pre-resolves teammate profiles for TEAM commitments so the TEAM commitment definition can reuse richer metadata.
34472
+ * Converts staged inline knowledge files into the final knowledge source URLs stored on requirements.
34186
34473
  *
34187
34474
  * @param requirements - Current requirements snapshot.
34188
- * @param commitment - Commitment currently being prepared.
34189
- * @param commitmentContent - Already resolved TEAM commitment content.
34190
- * @param options - Optional teammate profile resolvers.
34191
- * @returns Requirements with pre-resolved teammate profiles stored in metadata when possible.
34475
+ * @param uploader - Optional uploader for inline knowledge files.
34476
+ * @returns Requirements with inline knowledge converted into upload URLs or data URLs.
34192
34477
  *
34193
- * @private internal utility of `applyCommitmentsToRequirements`
34478
+ * @private function of `createAgentModelRequirementsWithCommitments`
34194
34479
  */
34195
- async function preResolveTeammateProfilesForTeamCommitment(requirements, commitment, commitmentContent, options) {
34480
+ async function materializeInlineKnowledgeSources(requirements, uploader) {
34196
34481
  var _a;
34197
- const profileResolver = (_a = options === null || options === void 0 ? void 0 : options.teammateProfileResolver) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.agentReferenceResolver;
34198
- if (commitment.type !== 'TEAM' || !(profileResolver === null || profileResolver === void 0 ? void 0 : profileResolver.resolveTeammateProfile)) {
34482
+ const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
34483
+ if (inlineSources.length === 0) {
34199
34484
  return requirements;
34200
34485
  }
34201
- try {
34202
- const parsedTeammates = parseTeamCommitmentContent(commitmentContent, { strict: false });
34203
- const preResolvedTeammateProfiles = clonePreResolvedTeammateProfiles(requirements._metadata);
34204
- for (const teammate of parsedTeammates) {
34205
- if (preResolvedTeammateProfiles[teammate.url]) {
34206
- continue;
34207
- }
34208
- const profile = await profileResolver.resolveTeammateProfile(teammate.url);
34209
- if (profile) {
34210
- preResolvedTeammateProfiles[teammate.url] = profile;
34211
- }
34212
- }
34213
- return {
34214
- ...requirements,
34215
- _metadata: {
34216
- ...requirements._metadata,
34217
- preResolvedTeammateProfiles,
34218
- },
34219
- };
34220
- }
34221
- catch (error) {
34222
- console.warn('Failed to pre-resolve teammate profiles for TEAM commitment:', error);
34223
- return requirements;
34486
+ const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
34487
+ for (const inlineSource of inlineSources) {
34488
+ const url = uploader
34489
+ ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
34490
+ : inlineKnowledgeSourceToDataUrl(inlineSource);
34491
+ knowledgeSources.push(url);
34224
34492
  }
34225
- }
34226
- /**
34227
- * Clones the metadata bucket used to cache teammate profiles resolved ahead of TEAM commitment application.
34228
- *
34229
- * @param metadata - Current requirements metadata.
34230
- * @returns Mutable copy of the cached teammate profile map.
34231
- *
34232
- * @private internal utility of `preResolveTeammateProfilesForTeamCommitment`
34233
- */
34234
- function clonePreResolvedTeammateProfiles(metadata) {
34235
- var _a;
34236
34493
  return {
34237
- ...((_a = metadata === null || metadata === void 0 ? void 0 : metadata.preResolvedTeammateProfiles) !== null && _a !== void 0 ? _a : {}),
34494
+ ...requirements,
34495
+ knowledgeSources,
34496
+ _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
34238
34497
  };
34239
34498
  }
34240
34499
  /**
34241
- * Applies the registered commitment definition while isolating the failure handling from the main loop.
34500
+ * Uploads one inline knowledge source and falls back to a data URL when the upload fails.
34242
34501
  *
34243
- * @param requirements - Current requirements snapshot.
34244
- * @param commitment - Commitment whose definition should be applied.
34245
- * @param commitmentContent - Final content passed into the definition.
34246
- * @returns Updated requirements, or the original requirements when the commitment fails.
34502
+ * @param inlineSource - Inline knowledge file waiting for upload.
34503
+ * @param uploader - Upload implementation provided by the caller.
34504
+ * @returns Uploaded knowledge URL or a legacy data URL fallback.
34247
34505
  *
34248
- * @private internal utility of `applyCommitmentsToRequirements`
34506
+ * @private internal utility of `materializeInlineKnowledgeSources`
34249
34507
  */
34250
- function applyCommitmentDefinitionSafely(requirements, commitment, commitmentContent) {
34251
- const definition = getCommitmentDefinition(commitment.type);
34252
- if (!definition) {
34253
- return requirements;
34254
- }
34508
+ async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
34255
34509
  try {
34256
- return definition.applyToAgentModelRequirements(requirements, commitmentContent);
34510
+ return await uploader(inlineSource);
34257
34511
  }
34258
34512
  catch (error) {
34259
- console.warn(`Failed to apply commitment ${commitment.type}:`, error);
34260
- return requirements;
34513
+ console.error('[inline-knowledge] Failed to upload inline source', {
34514
+ filename: inlineSource.filename,
34515
+ error,
34516
+ });
34517
+ return inlineKnowledgeSourceToDataUrl(inlineSource);
34261
34518
  }
34262
34519
  }
34263
34520
  /**
34264
- * Imports text files referenced by IMPORT commitments and appends their transformed content to the system message.
34521
+ * Extracts inline knowledge sources cached in commitment metadata.
34265
34522
  *
34266
- * @param requirements - Requirements possibly containing `importedFileUrls`.
34267
- * @returns Requirements with imported file content appended to the system message.
34523
+ * @param metadata - Current requirements metadata.
34524
+ * @returns Inline knowledge files collected during commitment application.
34268
34525
  *
34269
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34526
+ * @private internal utility of `materializeInlineKnowledgeSources`
34270
34527
  */
34271
- async function importReferencedFiles(requirements) {
34272
- const importedFileUrls = requirements.importedFileUrls;
34273
- if (!importedFileUrls || importedFileUrls.length === 0) {
34274
- return requirements;
34275
- }
34276
- for (const fileUrl of importedFileUrls) {
34277
- try {
34278
- const importedContent = await createImportedFileSystemMessage(fileUrl);
34279
- requirements = appendSystemMessageSection(requirements, importedContent);
34280
- }
34281
- catch (error) {
34282
- console.warn(`Failed to import file ${fileUrl}:`, error);
34283
- }
34528
+ function extractInlineKnowledgeSources(metadata) {
34529
+ if (!metadata) {
34530
+ return [];
34284
34531
  }
34285
- return requirements;
34532
+ const value = metadata.inlineKnowledgeSources;
34533
+ return Array.isArray(value) ? value : [];
34286
34534
  }
34287
34535
  /**
34288
- * Loads, validates, and transforms one imported file into a system-message block.
34536
+ * Removes inline-knowledge staging metadata after it has been materialized into final knowledge source URLs.
34289
34537
  *
34290
- * @param fileUrl - Remote URL or local path declared in an IMPORT commitment.
34291
- * @returns Imported text ready to append to the system message.
34538
+ * @param metadata - Current requirements metadata.
34539
+ * @returns Metadata without the temporary inline knowledge staging field.
34292
34540
  *
34293
- * @private internal utility of `importReferencedFiles`
34541
+ * @private internal utility of `materializeInlineKnowledgeSources`
34294
34542
  */
34295
- async function createImportedFileSystemMessage(fileUrl) {
34296
- await mockedSecurityCheck(fileUrl);
34297
- const { content, mimeType } = await readImportedFile(fileUrl);
34298
- if (isBinaryMimeType(mimeType)) {
34299
- throw new Error(`Importing binary files is not allowed: ${mimeType}`);
34300
- }
34301
- const plugin = $fileImportPlugins.find((fileImportPlugin) => fileImportPlugin.canImport(mimeType));
34302
- if (!plugin) {
34303
- throw new Error(`No import plugin found for MIME type: ${mimeType}`);
34543
+ function stripInlineKnowledgeMetadata(metadata) {
34544
+ if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
34545
+ return metadata;
34304
34546
  }
34305
- return plugin.import(content, mimeType);
34547
+ const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
34548
+ return Object.keys(rest).length > 0 ? rest : undefined;
34306
34549
  }
34550
+
34307
34551
  /**
34308
- * Reads one imported file and normalizes the MIME type expected by file import plugins.
34552
+ * Removes single-hash comment lines (`# Comment`) from a system message
34553
+ * This is used to clean up the final system message before sending it to the AI model
34554
+ * while preserving the original content with comments in metadata
34309
34555
  *
34310
- * @param fileUrl - Remote URL or local path declared in an IMPORT commitment.
34311
- * @returns Plain-text content together with a normalized MIME type.
34556
+ * @param systemMessage The system message that may contain comment lines
34557
+ * @returns The system message with single-hash comment lines removed
34312
34558
  *
34313
- * @private internal utility of `createImportedFileSystemMessage`
34559
+ * @private - TODO: [🧠] Maybe should be public?
34314
34560
  */
34315
- async function readImportedFile(fileUrl) {
34316
- if (isValidUrl(fileUrl)) {
34317
- const response = await promptbookFetch(fileUrl);
34318
- if (!response.ok) {
34319
- throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`);
34320
- }
34321
- return {
34322
- content: await response.text(),
34323
- mimeType: normalizeImportedMimeType(response.headers.get('Content-Type')),
34324
- };
34561
+ function removeCommentsFromSystemMessage(systemMessage) {
34562
+ if (!systemMessage) {
34563
+ return systemMessage;
34325
34564
  }
34326
- /*
34327
- TODO: !!!! Commented out this case because we need to work in Browser-compatible mode in many packages, use passed `fs` instead
34328
- } else if (isValidFilePath(fileUrl)) {
34329
- // [x🟢x] This code is expected to run in Node environment if local files are used
34330
- const fs = await import('fs/promises');
34331
- content = await fs.readFile(fileUrl, 'utf-8');
34332
- const extension = getFileExtension(fileUrl);
34333
- mimeType = extensionToMimeType(extension as string);
34334
- */
34335
- throw new Error(`Invalid file URL or path: ${fileUrl}`);
34565
+ const lines = systemMessage.split(/\r?\n/);
34566
+ const filteredLines = lines.filter((line) => {
34567
+ const trimmedLine = line.trim();
34568
+ // Remove only single-hash comment markers (`# Comment`) and keep markdown headings (`## Heading`).
34569
+ return !/^#(?!#)\s/.test(trimmedLine);
34570
+ });
34571
+ return filteredLines.join('\n').trim();
34336
34572
  }
34573
+
34337
34574
  /**
34338
- * Normalizes MIME types returned by fetch so plugin lookup works on bare MIME values without charset suffixes.
34575
+ * Creates agent model requirements by parsing commitments, applying them in source order,
34576
+ * and finalizing derived sections such as imports, example interactions, and inline knowledge uploads.
34339
34577
  *
34340
- * @param mimeType - Raw response MIME type header.
34341
- * @returns Normalized MIME type fallbacking to `text/plain`.
34578
+ * @param agentSource - Agent source book to parse.
34579
+ * @param modelName - Optional override for the agent model name.
34580
+ * @param options - Additional options such as reference and teammate resolvers.
34581
+ * @returns Fully prepared model requirements for the parsed agent source.
34342
34582
  *
34343
- * @private internal utility of `readImportedFile`
34583
+ * @private internal utility of `createAgentModelRequirements`
34344
34584
  */
34345
- function normalizeImportedMimeType(mimeType) {
34346
- return (mimeType || 'text/plain').split(';')[0].trim();
34585
+ async function createAgentModelRequirementsWithCommitments(agentSource, modelName, options) {
34586
+ const parseResult = parseAgentSourceWithCommitments(agentSource);
34587
+ const filteredCommitments = filterCommitmentsForAgentModelRequirements(parseResult.commitments);
34588
+ let requirements = createInitialAgentModelRequirements(parseResult.agentName, modelName);
34589
+ requirements = await applyCommitmentsToAgentModelRequirements(requirements, filteredCommitments, options);
34590
+ requirements = aggregateUseCommitmentSystemMessages(requirements, filteredCommitments);
34591
+ requirements = await augmentAgentModelRequirementsFromSource(requirements, parseResult, agentSource);
34592
+ requirements = await materializeInlineKnowledgeSources(requirements, options === null || options === void 0 ? void 0 : options.inlineKnowledgeSourceUploader);
34593
+ return finalizeRequirements(requirements);
34347
34594
  }
34348
34595
  /**
34349
- * Appends extracted MCP server identifiers from the original source.
34596
+ * Creates the initial requirements object with the parsed agent name stored in metadata and an optional model override.
34350
34597
  *
34351
- * @param requirements - Current requirements snapshot.
34352
- * @param agentSource - Original agent source used for MCP extraction.
34353
- * @returns Requirements with `mcpServers` set when MCP commitments are present.
34598
+ * @param agentName - Parsed agent name from the source prelude.
34599
+ * @param modelName - Optional explicit model name override.
34600
+ * @returns Initial requirements before any commitment is applied.
34354
34601
  *
34355
34602
  * @private internal utility of `createAgentModelRequirementsWithCommitments`
34356
34603
  */
34357
- function appendMcpServers(requirements, agentSource) {
34358
- const mcpServers = extractMcpServers(agentSource);
34359
- if (mcpServers.length === 0) {
34360
- return requirements;
34604
+ function createInitialAgentModelRequirements(agentName, modelName) {
34605
+ const initialRequirements = createBasicAgentModelRequirements(agentName);
34606
+ const requirementsWithMetadata = {
34607
+ ...initialRequirements,
34608
+ _metadata: {
34609
+ ...initialRequirements._metadata,
34610
+ agentName,
34611
+ },
34612
+ };
34613
+ if (!modelName) {
34614
+ return requirementsWithMetadata;
34361
34615
  }
34362
34616
  return {
34363
- ...requirements,
34364
- mcpServers,
34617
+ ...requirementsWithMetadata,
34618
+ modelName,
34365
34619
  };
34366
34620
  }
34367
34621
  /**
34368
- * Appends non-commitment prose from the source after filtering out blank lines and markdown horizontal rules.
34622
+ * Performs the final system-message cleanup pass after all other augmentation steps are complete.
34369
34623
  *
34370
- * @param requirements - Current requirements snapshot.
34371
- * @param parseResult - Parsed source including non-commitment lines.
34372
- * @returns Requirements with the remaining prose appended to the system message.
34624
+ * @param requirements - Fully built requirements before final cleanup.
34625
+ * @returns Requirements with comment lines removed from the final system message.
34373
34626
  *
34374
34627
  * @private internal utility of `createAgentModelRequirementsWithCommitments`
34375
34628
  */
34376
- function appendNonCommitmentContent(requirements, parseResult) {
34377
- const nonCommitmentContent = getNonCommitmentContent(parseResult);
34378
- if (!nonCommitmentContent) {
34379
- return requirements;
34380
- }
34381
- return appendSystemMessageSection(requirements, nonCommitmentContent);
34629
+ function finalizeRequirements(requirements) {
34630
+ return {
34631
+ ...requirements,
34632
+ systemMessage: removeCommentsFromSystemMessage(requirements.systemMessage),
34633
+ };
34382
34634
  }
34635
+
34383
34636
  /**
34384
- * Collects plain-text lines that were not parsed as commitments and should still become part of the final system message.
34385
- *
34386
- * @param parseResult - Parsed source including non-commitment lines.
34387
- * @returns Joined non-commitment content or an empty string when there is nothing to append.
34637
+ * Computes SHA-256 hash of the agent source
34388
34638
  *
34389
- * @private internal utility of `appendNonCommitmentContent`
34639
+ * @public exported from `@promptbook/core`
34390
34640
  */
34391
- function getNonCommitmentContent(parseResult) {
34392
- return parseResult.nonCommitmentLines
34393
- .filter((line, index) => index > 0 || !parseResult.agentName)
34394
- .filter((line) => line.trim())
34395
- .filter((line) => !isHorizontalLine(line))
34396
- .join('\n')
34397
- .trim();
34641
+ function computeAgentHash(agentSource) {
34642
+ return computeHash(agentSource);
34398
34643
  }
34644
+
34399
34645
  /**
34400
- * Checks whether a line is a markdown horizontal separator.
34646
+ * Normalizes agent name from arbitrary string to valid agent name
34401
34647
  *
34402
- * @param line - Source line to inspect.
34403
- * @returns `true` when the line is a thematic break.
34648
+ * Note: [🔂] This function is idempotent.
34404
34649
  *
34405
- * @private internal utility of `getNonCommitmentContent`
34650
+ * @public exported from `@promptbook/core`
34406
34651
  */
34407
- function isHorizontalLine(line) {
34408
- return HORIZONTAL_LINE_PATTERN.test(line);
34652
+ function normalizeAgentName(rawAgentName) {
34653
+ return titleToName(spaceTrim$1(rawAgentName));
34409
34654
  }
34655
+
34410
34656
  /**
34411
- * Appends example interactions assembled from INITIAL MESSAGE and USER/AGENT sample commitments.
34657
+ * Creates temporary default agent name based on agent source hash
34412
34658
  *
34413
- * @param requirements - Current requirements snapshot.
34414
- * @param parseResult - Parsed source used to recover initial message content.
34415
- * @returns Requirements with the example interaction block appended when examples exist.
34659
+ * @public exported from `@promptbook/core`
34660
+ */
34661
+ function createDefaultAgentName(agentSource) {
34662
+ const agentHash = computeAgentHash(agentSource);
34663
+ return normalizeAgentName(`Agent ${agentHash.substring(0, LIMITS.SHORT_NAME_LENGTH)}`);
34664
+ }
34665
+
34666
+ /**
34667
+ * Ensures the parsed profile always exposes a fullname value.
34416
34668
  *
34417
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34669
+ * @private internal utility of `parseAgentSource`
34418
34670
  */
34419
- function appendExampleInteractions(requirements, parseResult) {
34420
- const exampleInteractionsContent = createExampleInteractionsContent(parseResult, requirements.samples);
34421
- if (!exampleInteractionsContent) {
34422
- return requirements;
34671
+ function ensureMetaFullname(meta, fallbackFullname) {
34672
+ if (!meta.fullname) {
34673
+ meta.fullname = fallbackFullname;
34423
34674
  }
34424
- return appendSystemMessageSection(requirements, exampleInteractionsContent);
34425
34675
  }
34676
+
34426
34677
  /**
34427
- * Creates the formatted example-interaction section appended to the final system message.
34428
- *
34429
- * @param parseResult - Parsed source used to recover the initial message commitment.
34430
- * @param samples - Parsed USER/AGENT sample pairs already stored on requirements.
34431
- * @returns Formatted example interaction block or `null` when no examples exist.
34678
+ * Resolves the public agent profile text from the last GOAL/GOALS commitment,
34679
+ * falling back to the deprecated PERSONA/PERSONAE commitments when no goal exists.
34432
34680
  *
34433
- * @private internal utility of `appendExampleInteractions`
34681
+ * @private internal utility of `parseAgentSource`
34434
34682
  */
34435
- function createExampleInteractionsContent(parseResult, samples) {
34436
- const examples = collectExampleInteractionLines(parseResult, samples);
34437
- if (examples.length === 0) {
34438
- return null;
34683
+ function extractAgentProfileText(commitments) {
34684
+ let goalDescription = '';
34685
+ let hasGoalDescription = false;
34686
+ let personaDescription = '';
34687
+ let hasPersonaDescription = false;
34688
+ for (const commitment of commitments) {
34689
+ if (commitment.type === 'GOAL' || commitment.type === 'GOALS') {
34690
+ goalDescription = commitment.content;
34691
+ hasGoalDescription = true;
34692
+ }
34693
+ if (commitment.type === 'PERSONA' || commitment.type === 'PERSONAE') {
34694
+ personaDescription = commitment.content;
34695
+ hasPersonaDescription = true;
34696
+ }
34439
34697
  }
34440
- return `Example interaction:\n\n${examples.join('\n\n')}`;
34698
+ if (hasGoalDescription) {
34699
+ return goalDescription;
34700
+ }
34701
+ if (hasPersonaDescription) {
34702
+ return personaDescription;
34703
+ }
34704
+ return null;
34441
34705
  }
34706
+
34442
34707
  /**
34443
- * Collects the individual lines used in the example interaction section.
34444
- *
34445
- * @param parseResult - Parsed source used to recover the initial message commitment.
34446
- * @param samples - Parsed USER/AGENT sample pairs already stored on requirements.
34447
- * @returns Individual example interaction snippets in output order.
34708
+ * Resolves the last INITIAL MESSAGE commitment, which is the public initial-message value.
34448
34709
  *
34449
- * @private internal utility of `createExampleInteractionsContent`
34710
+ * @private internal utility of `parseAgentSource`
34450
34711
  */
34451
- function collectExampleInteractionLines(parseResult, samples) {
34452
- var _a;
34453
- const examples = [];
34454
- const initialMessage = (_a = parseResult.commitments.find((commitment) => commitment.type === 'INITIAL MESSAGE')) === null || _a === void 0 ? void 0 : _a.content;
34455
- if (initialMessage) {
34456
- examples.push(`Agent: ${initialMessage}`);
34457
- }
34458
- if (samples && samples.length > 0) {
34459
- for (const sample of samples) {
34460
- examples.push(`User: ${sample.question}\nAgent: ${sample.answer}`);
34712
+ function extractInitialMessage(commitments) {
34713
+ let initialMessage = null;
34714
+ for (const commitment of commitments) {
34715
+ if (commitment.type === 'INITIAL MESSAGE') {
34716
+ initialMessage = commitment.content;
34461
34717
  }
34462
34718
  }
34463
- return examples;
34719
+ return initialMessage;
34464
34720
  }
34721
+
34465
34722
  /**
34466
- * Appends a single system-message section using the same blank-line separation used throughout the original implementation.
34723
+ * Normalizes a domain-like string into a comparable hostname form.
34467
34724
  *
34468
- * @param requirements - Current requirements snapshot.
34469
- * @param section - Section content to append.
34470
- * @returns Requirements with the additional system-message block appended.
34725
+ * The returned value is lowercased and stripped to hostname only
34726
+ * (protocol, path, query, hash, and port are removed).
34471
34727
  *
34472
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34728
+ * @param rawDomain - Raw domain value (for example `my-agent.com` or `https://my-agent.com/path`).
34729
+ * @returns Normalized hostname or `null` when the value cannot be normalized.
34730
+ *
34731
+ * @private utility for host/domain matching
34473
34732
  */
34474
- function appendSystemMessageSection(requirements, section) {
34475
- return {
34476
- ...requirements,
34477
- systemMessage: requirements.systemMessage + '\n\n' + section,
34478
- };
34733
+ function normalizeDomainForMatching(rawDomain) {
34734
+ const trimmedDomain = rawDomain.trim();
34735
+ if (!trimmedDomain) {
34736
+ return null;
34737
+ }
34738
+ const candidateUrl = hasHttpProtocol(trimmedDomain) ? trimmedDomain : `https://${trimmedDomain}`;
34739
+ try {
34740
+ const parsedUrl = new URL(candidateUrl);
34741
+ const normalizedHostname = parsedUrl.hostname.trim().toLowerCase();
34742
+ return normalizedHostname || null;
34743
+ }
34744
+ catch (_a) {
34745
+ return null;
34746
+ }
34479
34747
  }
34480
34748
  /**
34481
- * Performs the final system-message cleanup pass after all other augmentation steps are complete.
34749
+ * Checks whether the value already includes an HTTP(S) protocol prefix.
34482
34750
  *
34483
- * @param requirements - Fully built requirements before final cleanup.
34484
- * @returns Requirements with comment lines removed from the final system message.
34751
+ * @param value - Raw value to inspect.
34752
+ * @returns True when the value starts with `http://` or `https://`.
34485
34753
  *
34486
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34754
+ * @private utility for host/domain matching
34487
34755
  */
34488
- function finalizeRequirements(requirements) {
34489
- return {
34490
- ...requirements,
34491
- systemMessage: removeCommentsFromSystemMessage(requirements.systemMessage),
34492
- };
34756
+ function hasHttpProtocol(value) {
34757
+ return value.startsWith('http://') || value.startsWith('https://');
34493
34758
  }
34759
+
34494
34760
  /**
34495
- * Attempts to upload inline knowledge entries, falling back to legacy data URLs when the upload fails or is not configured.
34496
- *
34497
- * @param requirements - Current requirements snapshot.
34498
- * @param uploader - Optional uploader for inline knowledge files.
34499
- * @returns Requirements with inline knowledge converted into upload URLs or data URLs.
34761
+ * Dedicated handlers for META-style commitments that directly map onto parsed meta fields.
34762
+ */
34763
+ const META_COMMITMENT_APPLIERS = {
34764
+ 'META AVATAR': applyMetaAvatarContent,
34765
+ 'META LINK': applyMetaLinkContent,
34766
+ 'META DOMAIN': applyMetaDomainContent,
34767
+ 'META IMAGE': applyMetaImageContent,
34768
+ 'META DESCRIPTION': applyMetaDescriptionContent,
34769
+ 'META DISCLAIMER': applyMetaDisclaimerContent,
34770
+ 'META INPUT PLACEHOLDER': applyMetaInputPlaceholderContent,
34771
+ 'MESSAGE SUFFIX': applyMessageSuffixContent,
34772
+ 'META COLOR': applyMetaColorContent,
34773
+ 'META FONT': applyMetaFontContent,
34774
+ 'META VOICE': applyMetaVoiceContent,
34775
+ };
34776
+ /**
34777
+ * Applies META-style commitments that mutate parsed profile metadata.
34500
34778
  *
34501
- * @private internal utility of `createAgentModelRequirementsWithCommitments`
34779
+ * @private internal utility of `parseAgentSource`
34502
34780
  */
34503
- async function applyPendingInlineKnowledgeSources(requirements, uploader) {
34504
- var _a;
34505
- const inlineSources = extractInlineKnowledgeSources(requirements._metadata);
34506
- if (inlineSources.length === 0) {
34507
- return requirements;
34781
+ function applyMetaCommitment(state, commitment) {
34782
+ const applyMetaContent = META_COMMITMENT_APPLIERS[commitment.type];
34783
+ if (applyMetaContent) {
34784
+ applyMetaContent(state, commitment.content);
34785
+ return;
34508
34786
  }
34509
- const knowledgeSources = [...((_a = requirements.knowledgeSources) !== null && _a !== void 0 ? _a : [])];
34510
- for (const inlineSource of inlineSources) {
34511
- const url = uploader
34512
- ? await uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader)
34513
- : inlineKnowledgeSourceToDataUrl(inlineSource);
34514
- knowledgeSources.push(url);
34787
+ if (commitment.type === 'META') {
34788
+ applyGenericMetaCommitment(state, commitment.content);
34515
34789
  }
34516
- return {
34517
- ...requirements,
34518
- knowledgeSources,
34519
- _metadata: stripInlineKnowledgeMetadata(requirements._metadata),
34520
- };
34521
34790
  }
34522
34791
  /**
34523
- * Uploads one inline knowledge source and falls back to a data URL when the upload fails.
34524
- *
34525
- * @param inlineSource - Inline knowledge file waiting for upload.
34526
- * @param uploader - Upload implementation provided by the caller.
34527
- * @returns Uploaded knowledge URL or a legacy data URL fallback.
34528
- *
34529
- * @private internal utility of `applyPendingInlineKnowledgeSources`
34792
+ * Applies the generic META commitment form (`META TYPE value`).
34530
34793
  */
34531
- async function uploadInlineKnowledgeSourceWithFallback(inlineSource, uploader) {
34532
- try {
34533
- return await uploader(inlineSource);
34794
+ function applyGenericMetaCommitment(state, content) {
34795
+ const metaTypeRaw = content.split(' ')[0] || 'NONE';
34796
+ const metaValue = spaceTrim$1(content.substring(metaTypeRaw.length));
34797
+ if (metaTypeRaw === 'LINK') {
34798
+ state.links.push(metaValue);
34534
34799
  }
34535
- catch (error) {
34536
- console.error('[inline-knowledge] Failed to upload inline source', {
34537
- filename: inlineSource.filename,
34538
- error,
34539
- });
34540
- return inlineKnowledgeSourceToDataUrl(inlineSource);
34800
+ if (metaTypeRaw.toUpperCase() === 'AVATAR') {
34801
+ applyMetaAvatarContent(state, metaValue);
34802
+ return;
34541
34803
  }
34804
+ const metaType = normalizeTo_camelCase(metaTypeRaw);
34805
+ state.meta[metaType] = metaValue;
34542
34806
  }
34543
34807
  /**
34544
- * Extracts inline knowledge sources cached in commitment metadata.
34545
- *
34546
- * @param metadata - Current requirements metadata.
34547
- * @returns Inline knowledge files collected during commitment application.
34548
- *
34549
- * @private internal utility of `applyPendingInlineKnowledgeSources`
34808
+ * Applies META AVATAR content into the canonical `meta.avatar` field.
34550
34809
  */
34551
- function extractInlineKnowledgeSources(metadata) {
34552
- if (!metadata) {
34553
- return [];
34810
+ function applyMetaAvatarContent(state, content) {
34811
+ const avatarVisualId = resolveAvatarVisualId(content);
34812
+ if (avatarVisualId) {
34813
+ state.meta.avatar = avatarVisualId;
34814
+ return;
34554
34815
  }
34555
- const value = metadata.inlineKnowledgeSources;
34556
- return Array.isArray(value) ? value : [];
34816
+ delete state.meta.avatar;
34557
34817
  }
34558
34818
  /**
34559
- * Removes inline-knowledge staging metadata after it has been materialized into final knowledge source URLs.
34560
- *
34561
- * @param metadata - Current requirements metadata.
34562
- * @returns Metadata without the temporary inline knowledge staging field.
34563
- *
34564
- * @private internal utility of `applyPendingInlineKnowledgeSources`
34819
+ * Applies META LINK content into links and the canonical `meta.link` field.
34565
34820
  */
34566
- function stripInlineKnowledgeMetadata(metadata) {
34567
- if (!metadata || !Object.prototype.hasOwnProperty.call(metadata, 'inlineKnowledgeSources')) {
34568
- return metadata;
34569
- }
34570
- const { inlineKnowledgeSources: _unusedInlineKnowledgeSources, ...rest } = metadata;
34571
- return Object.keys(rest).length > 0 ? rest : undefined;
34821
+ function applyMetaLinkContent(state, content) {
34822
+ const linkValue = spaceTrim$1(content);
34823
+ state.links.push(linkValue);
34824
+ state.meta.link = linkValue;
34572
34825
  }
34573
34826
  /**
34574
- * Mocked security check for imported files.
34575
- *
34576
- * @param urlOrPath - The URL or local path of the file to check.
34577
- * @returns A promise that resolves if the file is considered safe.
34578
- *
34579
- * @private internal utility of `createImportedFileSystemMessage`
34827
+ * Applies META DOMAIN content into the normalized `meta.domain` field.
34580
34828
  */
34581
- async function mockedSecurityCheck(urlOrPath) {
34582
- // TODO: Implement proper security checks
34583
- await new Promise((resolve) => setTimeout(resolve, 10));
34584
- if (urlOrPath.includes('malicious')) {
34585
- throw new Error(`Security check failed for: ${urlOrPath}`);
34586
- }
34829
+ function applyMetaDomainContent(state, content) {
34830
+ state.meta.domain = normalizeMetaDomain(content);
34831
+ }
34832
+ /**
34833
+ * Applies META IMAGE content into the canonical `meta.image` field.
34834
+ */
34835
+ function applyMetaImageContent(state, content) {
34836
+ state.meta.image = spaceTrim$1(content);
34837
+ }
34838
+ /**
34839
+ * Applies META DESCRIPTION content into the canonical `meta.description` field.
34840
+ */
34841
+ function applyMetaDescriptionContent(state, content) {
34842
+ state.meta.description = spaceTrim$1(content);
34843
+ }
34844
+ /**
34845
+ * Applies META DISCLAIMER content into the canonical `meta.disclaimer` field.
34846
+ */
34847
+ function applyMetaDisclaimerContent(state, content) {
34848
+ state.meta.disclaimer = content;
34587
34849
  }
34588
34850
  /**
34589
- * Checks whether the given MIME type belongs to a binary file.
34590
- *
34591
- * @param mimeType - The MIME type to check.
34592
- * @returns `true` when the MIME type is treated as binary.
34593
- *
34594
- * @private internal utility of `createImportedFileSystemMessage`
34851
+ * Applies META INPUT PLACEHOLDER content into the canonical `meta.inputPlaceholder` field.
34595
34852
  */
34596
- function isBinaryMimeType(mimeType) {
34597
- return BINARY_MIME_TYPE_PREFIXES.some((prefix) => mimeType.startsWith(prefix));
34853
+ function applyMetaInputPlaceholderContent(state, content) {
34854
+ state.meta.inputPlaceholder = spaceTrim$1(content);
34598
34855
  }
34599
-
34600
34856
  /**
34601
- * Normalizes a domain-like string into a comparable hostname form.
34602
- *
34603
- * The returned value is lowercased and stripped to hostname only
34604
- * (protocol, path, query, hash, and port are removed).
34605
- *
34606
- * @param rawDomain - Raw domain value (for example `my-agent.com` or `https://my-agent.com/path`).
34607
- * @returns Normalized hostname or `null` when the value cannot be normalized.
34608
- *
34609
- * @private utility for host/domain matching
34857
+ * Applies MESSAGE SUFFIX content into the canonical `meta.messageSuffix` field.
34610
34858
  */
34611
- function normalizeDomainForMatching(rawDomain) {
34612
- const trimmedDomain = rawDomain.trim();
34613
- if (!trimmedDomain) {
34614
- return null;
34615
- }
34616
- const candidateUrl = hasHttpProtocol(trimmedDomain) ? trimmedDomain : `https://${trimmedDomain}`;
34617
- try {
34618
- const parsedUrl = new URL(candidateUrl);
34619
- const normalizedHostname = parsedUrl.hostname.trim().toLowerCase();
34620
- return normalizedHostname || null;
34621
- }
34622
- catch (_a) {
34623
- return null;
34624
- }
34859
+ function applyMessageSuffixContent(state, content) {
34860
+ state.meta.messageSuffix = content;
34625
34861
  }
34626
34862
  /**
34627
- * Checks whether the value already includes an HTTP(S) protocol prefix.
34628
- *
34629
- * @param value - Raw value to inspect.
34630
- * @returns True when the value starts with `http://` or `https://`.
34631
- *
34632
- * @private utility for host/domain matching
34863
+ * Applies META COLOR content into the canonical `meta.color` field.
34633
34864
  */
34634
- function hasHttpProtocol(value) {
34635
- return value.startsWith('http://') || value.startsWith('https://');
34865
+ function applyMetaColorContent(state, content) {
34866
+ state.meta.color = normalizeSeparator(content);
34636
34867
  }
34637
-
34638
34868
  /**
34639
- * Computes SHA-256 hash of the agent source
34640
- *
34641
- * @public exported from `@promptbook/core`
34869
+ * Applies META FONT content into the canonical `meta.font` field.
34642
34870
  */
34643
- function computeAgentHash(agentSource) {
34644
- return computeHash(agentSource);
34871
+ function applyMetaFontContent(state, content) {
34872
+ state.meta.font = normalizeSeparator(content);
34645
34873
  }
34646
-
34647
34874
  /**
34648
- * Normalizes agent name from arbitrary string to valid agent name
34649
- *
34650
- * Note: [🔂] This function is idempotent.
34875
+ * Applies META VOICE content into the canonical `meta.voice` field.
34876
+ */
34877
+ function applyMetaVoiceContent(state, content) {
34878
+ state.meta.voice = spaceTrim$1(content);
34879
+ }
34880
+ /**
34881
+ * Normalizes the separator in the content
34651
34882
  *
34652
- * @public exported from `@promptbook/core`
34883
+ * @param content - The content to normalize
34884
+ * @returns The content with normalized separators
34653
34885
  */
34654
- function normalizeAgentName(rawAgentName) {
34655
- return titleToName(spaceTrim$1(rawAgentName));
34886
+ function normalizeSeparator(content) {
34887
+ const trimmed = spaceTrim$1(content);
34888
+ if (trimmed.includes(',')) {
34889
+ return trimmed;
34890
+ }
34891
+ return trimmed.split(/\s+/).join(', ');
34656
34892
  }
34657
-
34658
34893
  /**
34659
- * Creates temporary default agent name based on agent source hash
34894
+ * Normalizes META DOMAIN content to a hostname-like value when possible.
34660
34895
  *
34661
- * @public exported from `@promptbook/core`
34896
+ * @param content - Raw META DOMAIN content.
34897
+ * @returns Normalized domain or a trimmed fallback.
34662
34898
  */
34663
- function createDefaultAgentName(agentSource) {
34664
- const agentHash = computeAgentHash(agentSource);
34665
- return normalizeAgentName(`Agent ${agentHash.substring(0, LIMITS.SHORT_NAME_LENGTH)}`);
34899
+ function normalizeMetaDomain(content) {
34900
+ const trimmed = spaceTrim$1(content);
34901
+ return normalizeDomainForMatching(trimmed) || trimmed.toLowerCase();
34666
34902
  }
34667
34903
 
34668
34904
  /**
34669
- * Parses basic information from agent source
34670
- *
34671
- * There are 2 similar functions:
34672
- * - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
34673
- * - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
34905
+ * Updates sample-conversation state for communication commitments.
34674
34906
  *
34675
- * @public exported from `@promptbook/core`
34907
+ * @private internal utility of `parseAgentSource`
34676
34908
  */
34677
- function parseAgentSource(agentSource) {
34678
- const parseResult = parseAgentSourceWithCommitments(agentSource);
34679
- const resolvedAgentName = parseResult.agentName || createDefaultAgentName(agentSource);
34680
- const personaDescription = extractAgentProfileText(parseResult.commitments);
34681
- const initialMessage = extractInitialMessage(parseResult.commitments);
34682
- const parsedProfile = extractParsedAgentProfile(parseResult.commitments);
34683
- ensureMetaFullname(parsedProfile.meta, resolvedAgentName);
34684
- return {
34685
- agentName: normalizeAgentName(resolvedAgentName),
34686
- agentHash: computeAgentHash(agentSource),
34687
- permanentId: parsedProfile.meta.id,
34688
- personaDescription,
34689
- initialMessage,
34690
- meta: parsedProfile.meta,
34691
- links: parsedProfile.links,
34692
- parameters: parseParameters(agentSource),
34693
- capabilities: parsedProfile.capabilities,
34694
- samples: parsedProfile.samples,
34695
- knowledgeSources: parsedProfile.knowledgeSources,
34696
- };
34909
+ function consumeConversationSampleCommitment(state, commitment) {
34910
+ switch (commitment.type) {
34911
+ case 'INITIAL MESSAGE':
34912
+ state.samples.push({ question: null, answer: commitment.content });
34913
+ return true;
34914
+ case 'USER MESSAGE':
34915
+ state.pendingUserMessage = commitment.content;
34916
+ return true;
34917
+ case 'INTERNAL MESSAGE':
34918
+ // INTERNAL MESSAGE stores trace payloads and is intentionally ignored in basic profile samples.
34919
+ return true;
34920
+ case 'AGENT MESSAGE':
34921
+ if (state.pendingUserMessage !== null) {
34922
+ state.samples.push({ question: state.pendingUserMessage, answer: commitment.content });
34923
+ state.pendingUserMessage = null;
34924
+ }
34925
+ return true;
34926
+ default:
34927
+ return false;
34928
+ }
34697
34929
  }
34930
+
34698
34931
  /**
34699
34932
  * Static capability descriptors for commitments that map one-to-one to a visible capability.
34700
- *
34701
- * @private internal utility of `parseAgentSource`
34702
34933
  */
34703
34934
  const SIMPLE_CAPABILITY_BY_COMMITMENT_TYPE = {
34704
34935
  'USE BROWSER': {
@@ -34762,141 +34993,10 @@ const SIMPLE_CAPABILITY_BY_COMMITMENT_TYPE = {
34762
34993
  iconName: 'Calendar',
34763
34994
  },
34764
34995
  };
34765
- /**
34766
- * Dedicated handlers for META-style commitments that directly map onto parsed meta fields.
34767
- *
34768
- * @private internal utility of `parseAgentSource`
34769
- */
34770
- const META_COMMITMENT_APPLIERS = {
34771
- 'META AVATAR': applyMetaAvatarContent,
34772
- 'META LINK': applyMetaLinkContent,
34773
- 'META DOMAIN': applyMetaDomainContent,
34774
- 'META IMAGE': applyMetaImageContent,
34775
- 'META DESCRIPTION': applyMetaDescriptionContent,
34776
- 'META DISCLAIMER': applyMetaDisclaimerContent,
34777
- 'META INPUT PLACEHOLDER': applyMetaInputPlaceholderContent,
34778
- 'MESSAGE SUFFIX': applyMessageSuffixContent,
34779
- 'META COLOR': applyMetaColorContent,
34780
- 'META FONT': applyMetaFontContent,
34781
- 'META VOICE': applyMetaVoiceContent,
34782
- };
34783
34996
  /**
34784
34997
  * Detects local slash-based references used by FROM and IMPORT commitments.
34785
- *
34786
- * @private internal utility of `parseAgentSource`
34787
34998
  */
34788
34999
  const LOCAL_AGENT_REFERENCE_PREFIXES = ['./', '../', '/'];
34789
- /**
34790
- * Resolves the public agent profile text from the last GOAL/GOALS commitment,
34791
- * falling back to the deprecated PERSONA/PERSONAE commitments when no goal exists.
34792
- *
34793
- * @private internal utility of `parseAgentSource`
34794
- */
34795
- function extractAgentProfileText(commitments) {
34796
- let goalDescription = '';
34797
- let hasGoalDescription = false;
34798
- let personaDescription = '';
34799
- let hasPersonaDescription = false;
34800
- for (const commitment of commitments) {
34801
- if (commitment.type === 'GOAL' || commitment.type === 'GOALS') {
34802
- goalDescription = commitment.content;
34803
- hasGoalDescription = true;
34804
- }
34805
- if (commitment.type === 'PERSONA' || commitment.type === 'PERSONAE') {
34806
- personaDescription = commitment.content;
34807
- hasPersonaDescription = true;
34808
- }
34809
- }
34810
- if (hasGoalDescription) {
34811
- return goalDescription;
34812
- }
34813
- if (hasPersonaDescription) {
34814
- return personaDescription;
34815
- }
34816
- return null;
34817
- }
34818
- /**
34819
- * Resolves the last INITIAL MESSAGE commitment, which is the public initial-message value.
34820
- *
34821
- * @private internal utility of `parseAgentSource`
34822
- */
34823
- function extractInitialMessage(commitments) {
34824
- let initialMessage = null;
34825
- for (const commitment of commitments) {
34826
- if (commitment.type === 'INITIAL MESSAGE') {
34827
- initialMessage = commitment.content;
34828
- }
34829
- }
34830
- return initialMessage;
34831
- }
34832
- /**
34833
- * Collects capability, sample, meta, link, and knowledge-source data from commitments.
34834
- *
34835
- * @private internal utility of `parseAgentSource`
34836
- */
34837
- function extractParsedAgentProfile(commitments) {
34838
- const state = {
34839
- meta: {},
34840
- links: [],
34841
- capabilities: [],
34842
- samples: [],
34843
- knowledgeSources: [],
34844
- pendingUserMessage: null,
34845
- knownKnowledgeSourceUrls: new Set(),
34846
- };
34847
- for (const commitment of commitments) {
34848
- processParsedCommitment(state, commitment);
34849
- }
34850
- return {
34851
- meta: state.meta,
34852
- links: state.links,
34853
- capabilities: state.capabilities,
34854
- samples: state.samples,
34855
- knowledgeSources: state.knowledgeSources,
34856
- };
34857
- }
34858
- /**
34859
- * Processes one parsed commitment through the sample, capability, and meta stages.
34860
- *
34861
- * @private internal utility of `parseAgentSource`
34862
- */
34863
- function processParsedCommitment(state, commitment) {
34864
- if (consumeConversationSampleCommitment(state, commitment)) {
34865
- return;
34866
- }
34867
- const capabilities = createCapabilitiesFromCommitment(state, commitment);
34868
- if (capabilities.length > 0) {
34869
- state.capabilities.push(...capabilities);
34870
- return;
34871
- }
34872
- applyMetaCommitment(state, commitment);
34873
- }
34874
- /**
34875
- * Updates sample-conversation state for communication commitments.
34876
- *
34877
- * @private internal utility of `parseAgentSource`
34878
- */
34879
- function consumeConversationSampleCommitment(state, commitment) {
34880
- switch (commitment.type) {
34881
- case 'INITIAL MESSAGE':
34882
- state.samples.push({ question: null, answer: commitment.content });
34883
- return true;
34884
- case 'USER MESSAGE':
34885
- state.pendingUserMessage = commitment.content;
34886
- return true;
34887
- case 'INTERNAL MESSAGE':
34888
- // INTERNAL MESSAGE stores trace payloads and is intentionally ignored in basic profile samples.
34889
- return true;
34890
- case 'AGENT MESSAGE':
34891
- if (state.pendingUserMessage !== null) {
34892
- state.samples.push({ question: state.pendingUserMessage, answer: commitment.content });
34893
- state.pendingUserMessage = null;
34894
- }
34895
- return true;
34896
- default:
34897
- return false;
34898
- }
34899
- }
34900
35000
  /**
34901
35001
  * Creates the visible capabilities produced by one parsed commitment.
34902
35002
  *
@@ -34926,8 +35026,6 @@ function createCapabilitiesFromCommitment(state, commitment) {
34926
35026
  }
34927
35027
  /**
34928
35028
  * Clones one static capability descriptor for a simple capability commitment.
34929
- *
34930
- * @private internal utility of `parseAgentSource`
34931
35029
  */
34932
35030
  function createSimpleCapability(commitmentType) {
34933
35031
  const capability = SIMPLE_CAPABILITY_BY_COMMITMENT_TYPE[commitmentType];
@@ -34935,8 +35033,6 @@ function createSimpleCapability(commitmentType) {
34935
35033
  }
34936
35034
  /**
34937
35035
  * Creates the USE PROJECT capability badge.
34938
- *
34939
- * @private internal utility of `parseAgentSource`
34940
35036
  */
34941
35037
  function createProjectCapability(content) {
34942
35038
  var _a;
@@ -34950,8 +35046,6 @@ function createProjectCapability(content) {
34950
35046
  }
34951
35047
  /**
34952
35048
  * Creates the FROM inheritance capability when the reference should stay visible in the profile.
34953
- *
34954
- * @private internal utility of `parseAgentSource`
34955
35049
  */
34956
35050
  function createInheritanceCapability(content) {
34957
35051
  const reference = extractFirstCommitmentLine(content);
@@ -34978,8 +35072,6 @@ function createInheritanceCapability(content) {
34978
35072
  }
34979
35073
  /**
34980
35074
  * Creates the IMPORT capability badge.
34981
- *
34982
- * @private internal utility of `parseAgentSource`
34983
35075
  */
34984
35076
  function createImportCapability(content) {
34985
35077
  const reference = extractFirstCommitmentLine(content);
@@ -35007,8 +35099,6 @@ function createImportCapability(content) {
35007
35099
  }
35008
35100
  /**
35009
35101
  * Creates TEAM capability badges for all parsed teammates.
35010
- *
35011
- * @private internal utility of `parseAgentSource`
35012
35102
  */
35013
35103
  function createTeamCapabilities(content) {
35014
35104
  const teammates = parseTeamCommitmentContent(content);
@@ -35021,8 +35111,6 @@ function createTeamCapabilities(content) {
35021
35111
  }
35022
35112
  /**
35023
35113
  * Creates the KNOWLEDGE capability badge and records URL-based knowledge sources.
35024
- *
35025
- * @private internal utility of `parseAgentSource`
35026
35114
  */
35027
35115
  function createKnowledgeCapability(state, content) {
35028
35116
  const trimmedContent = spaceTrim$1(content);
@@ -35037,8 +35125,6 @@ function createKnowledgeCapability(state, content) {
35037
35125
  }
35038
35126
  /**
35039
35127
  * Stores unique URL-based knowledge sources for later citation resolution.
35040
- *
35041
- * @private internal utility of `parseAgentSource`
35042
35128
  */
35043
35129
  function rememberKnowledgeSources(state, extractedUrls) {
35044
35130
  for (const extractedUrl of extractedUrls) {
@@ -35062,8 +35148,6 @@ function rememberKnowledgeSources(state, extractedUrls) {
35062
35148
  }
35063
35149
  /**
35064
35150
  * Derives the visible KNOWLEDGE badge label and icon from commitment content.
35065
- *
35066
- * @private internal utility of `parseAgentSource`
35067
35151
  */
35068
35152
  function createKnowledgeCapabilityPresentation(content, extractedUrls) {
35069
35153
  let label = content;
@@ -35096,8 +35180,6 @@ function createKnowledgeCapabilityPresentation(content, extractedUrls) {
35096
35180
  }
35097
35181
  /**
35098
35182
  * Shortens text-only KNOWLEDGE commitments into the same preview label as before.
35099
- *
35100
- * @private internal utility of `parseAgentSource`
35101
35183
  */
35102
35184
  function createKnowledgeTextLabel(content) {
35103
35185
  const words = content.split(/\s+/);
@@ -35106,186 +35188,89 @@ function createKnowledgeTextLabel(content) {
35106
35188
  }
35107
35189
  return content;
35108
35190
  }
35109
- /**
35110
- * Applies META-style commitments that mutate parsed profile metadata.
35111
- *
35112
- * @private internal utility of `parseAgentSource`
35113
- */
35114
- function applyMetaCommitment(state, commitment) {
35115
- const applyMetaContent = META_COMMITMENT_APPLIERS[commitment.type];
35116
- if (applyMetaContent) {
35117
- applyMetaContent(state, commitment.content);
35118
- return;
35119
- }
35120
- if (commitment.type === 'META') {
35121
- applyGenericMetaCommitment(state, commitment.content);
35122
- }
35123
- }
35124
- /**
35125
- * Applies the generic META commitment form (`META TYPE value`).
35126
- *
35127
- * @private internal utility of `parseAgentSource`
35128
- */
35129
- function applyGenericMetaCommitment(state, content) {
35130
- const metaTypeRaw = content.split(' ')[0] || 'NONE';
35131
- const metaValue = spaceTrim$1(content.substring(metaTypeRaw.length));
35132
- if (metaTypeRaw === 'LINK') {
35133
- state.links.push(metaValue);
35134
- }
35135
- if (metaTypeRaw.toUpperCase() === 'AVATAR') {
35136
- applyMetaAvatarContent(state, metaValue);
35137
- return;
35138
- }
35139
- const metaType = normalizeTo_camelCase(metaTypeRaw);
35140
- state.meta[metaType] = metaValue;
35141
- }
35142
- /**
35143
- * Applies META AVATAR content into the canonical `meta.avatar` field.
35144
- *
35145
- * @private internal utility of `parseAgentSource`
35146
- */
35147
- function applyMetaAvatarContent(state, content) {
35148
- const avatarVisualId = resolveAvatarVisualId(content);
35149
- if (avatarVisualId) {
35150
- state.meta.avatar = avatarVisualId;
35151
- return;
35152
- }
35153
- delete state.meta.avatar;
35154
- }
35155
- /**
35156
- * Applies META LINK content into links and the canonical `meta.link` field.
35157
- *
35158
- * @private internal utility of `parseAgentSource`
35159
- */
35160
- function applyMetaLinkContent(state, content) {
35161
- const linkValue = spaceTrim$1(content);
35162
- state.links.push(linkValue);
35163
- state.meta.link = linkValue;
35164
- }
35165
- /**
35166
- * Applies META DOMAIN content into the normalized `meta.domain` field.
35167
- *
35168
- * @private internal utility of `parseAgentSource`
35169
- */
35170
- function applyMetaDomainContent(state, content) {
35171
- state.meta.domain = normalizeMetaDomain(content);
35172
- }
35173
- /**
35174
- * Applies META IMAGE content into the canonical `meta.image` field.
35175
- *
35176
- * @private internal utility of `parseAgentSource`
35177
- */
35178
- function applyMetaImageContent(state, content) {
35179
- state.meta.image = spaceTrim$1(content);
35180
- }
35181
- /**
35182
- * Applies META DESCRIPTION content into the canonical `meta.description` field.
35183
- *
35184
- * @private internal utility of `parseAgentSource`
35185
- */
35186
- function applyMetaDescriptionContent(state, content) {
35187
- state.meta.description = spaceTrim$1(content);
35188
- }
35189
- /**
35190
- * Applies META DISCLAIMER content into the canonical `meta.disclaimer` field.
35191
- *
35192
- * @private internal utility of `parseAgentSource`
35193
- */
35194
- function applyMetaDisclaimerContent(state, content) {
35195
- state.meta.disclaimer = content;
35196
- }
35197
- /**
35198
- * Applies META INPUT PLACEHOLDER content into the canonical `meta.inputPlaceholder` field.
35199
- *
35200
- * @private internal utility of `parseAgentSource`
35201
- */
35202
- function applyMetaInputPlaceholderContent(state, content) {
35203
- state.meta.inputPlaceholder = spaceTrim$1(content);
35204
- }
35205
- /**
35206
- * Applies MESSAGE SUFFIX content into the canonical `meta.messageSuffix` field.
35207
- *
35208
- * @private internal utility of `parseAgentSource`
35209
- */
35210
- function applyMessageSuffixContent(state, content) {
35211
- state.meta.messageSuffix = content;
35212
- }
35213
- /**
35214
- * Applies META COLOR content into the canonical `meta.color` field.
35215
- *
35216
- * @private internal utility of `parseAgentSource`
35217
- */
35218
- function applyMetaColorContent(state, content) {
35219
- state.meta.color = normalizeSeparator(content);
35220
- }
35221
- /**
35222
- * Applies META FONT content into the canonical `meta.font` field.
35223
- *
35224
- * @private internal utility of `parseAgentSource`
35225
- */
35226
- function applyMetaFontContent(state, content) {
35227
- state.meta.font = normalizeSeparator(content);
35228
- }
35229
- /**
35230
- * Applies META VOICE content into the canonical `meta.voice` field.
35231
- *
35232
- * @private internal utility of `parseAgentSource`
35233
- */
35234
- function applyMetaVoiceContent(state, content) {
35235
- state.meta.voice = spaceTrim$1(content);
35236
- }
35237
- /**
35238
- * Ensures the parsed profile always exposes a fullname value.
35239
- *
35240
- * @private internal utility of `parseAgentSource`
35241
- */
35242
- function ensureMetaFullname(meta, fallbackFullname) {
35243
- if (!meta.fullname) {
35244
- meta.fullname = fallbackFullname;
35245
- }
35246
- }
35247
35191
  /**
35248
35192
  * Extracts the first logical line from multiline commitment content.
35249
- *
35250
- * @private internal utility of `parseAgentSource`
35251
35193
  */
35252
35194
  function extractFirstCommitmentLine(content) {
35253
35195
  return spaceTrim$1(content).split(/\r?\n/)[0] || '';
35254
35196
  }
35255
35197
  /**
35256
35198
  * Detects local FROM/IMPORT references that should use local-link labels and icons.
35257
- *
35258
- * @private internal utility of `parseAgentSource`
35259
35199
  */
35260
35200
  function isLocalAgentReference(reference) {
35261
35201
  return LOCAL_AGENT_REFERENCE_PREFIXES.some((prefix) => reference.startsWith(prefix));
35262
35202
  }
35203
+
35263
35204
  /**
35264
- * Normalizes the separator in the content
35265
- *
35266
- * @param content - The content to normalize
35267
- * @returns The content with normalized separators
35205
+ * Collects capability, sample, meta, link, and knowledge-source data from commitments.
35268
35206
  *
35269
35207
  * @private internal utility of `parseAgentSource`
35270
35208
  */
35271
- function normalizeSeparator(content) {
35272
- const trimmed = spaceTrim$1(content);
35273
- if (trimmed.includes(',')) {
35274
- return trimmed;
35209
+ function extractParsedAgentProfile(commitments) {
35210
+ const state = {
35211
+ meta: {},
35212
+ links: [],
35213
+ capabilities: [],
35214
+ samples: [],
35215
+ knowledgeSources: [],
35216
+ pendingUserMessage: null,
35217
+ knownKnowledgeSourceUrls: new Set(),
35218
+ };
35219
+ for (const commitment of commitments) {
35220
+ processParsedCommitment(state, commitment);
35275
35221
  }
35276
- return trimmed.split(/\s+/).join(', ');
35222
+ return {
35223
+ meta: state.meta,
35224
+ links: state.links,
35225
+ capabilities: state.capabilities,
35226
+ samples: state.samples,
35227
+ knowledgeSources: state.knowledgeSources,
35228
+ };
35277
35229
  }
35278
35230
  /**
35279
- * Normalizes META DOMAIN content to a hostname-like value when possible.
35231
+ * Processes one parsed commitment through the sample, capability, and meta stages.
35232
+ */
35233
+ function processParsedCommitment(state, commitment) {
35234
+ if (consumeConversationSampleCommitment(state, commitment)) {
35235
+ return;
35236
+ }
35237
+ const capabilities = createCapabilitiesFromCommitment(state, commitment);
35238
+ if (capabilities.length > 0) {
35239
+ state.capabilities.push(...capabilities);
35240
+ return;
35241
+ }
35242
+ applyMetaCommitment(state, commitment);
35243
+ }
35244
+
35245
+ /**
35246
+ * Parses basic information from agent source
35280
35247
  *
35281
- * @param content - Raw META DOMAIN content.
35282
- * @returns Normalized domain or a trimmed fallback.
35248
+ * There are 2 similar functions:
35249
+ * - `parseAgentSource` which is a lightweight parser for agent source, it parses basic information and its purpose is to be quick and synchronous. The commitments there are hardcoded.
35250
+ * - `createAgentModelRequirements` which is an asynchronous function that creates model requirements it applies each commitment one by one and works asynchronously.
35283
35251
  *
35284
- * @private internal utility of `parseAgentSource`
35252
+ * @public exported from `@promptbook/core`
35285
35253
  */
35286
- function normalizeMetaDomain(content) {
35287
- const trimmed = spaceTrim$1(content);
35288
- return normalizeDomainForMatching(trimmed) || trimmed.toLowerCase();
35254
+ function parseAgentSource(agentSource) {
35255
+ const parseResult = parseAgentSourceWithCommitments(agentSource);
35256
+ const resolvedAgentName = parseResult.agentName || createDefaultAgentName(agentSource);
35257
+ const personaDescription = extractAgentProfileText(parseResult.commitments);
35258
+ const initialMessage = extractInitialMessage(parseResult.commitments);
35259
+ const parsedProfile = extractParsedAgentProfile(parseResult.commitments);
35260
+ ensureMetaFullname(parsedProfile.meta, resolvedAgentName);
35261
+ return {
35262
+ agentName: normalizeAgentName(resolvedAgentName),
35263
+ agentHash: computeAgentHash(agentSource),
35264
+ permanentId: parsedProfile.meta.id,
35265
+ personaDescription,
35266
+ initialMessage,
35267
+ meta: parsedProfile.meta,
35268
+ links: parsedProfile.links,
35269
+ parameters: parseParameters(agentSource),
35270
+ capabilities: parsedProfile.capabilities,
35271
+ samples: parsedProfile.samples,
35272
+ knowledgeSources: parsedProfile.knowledgeSources,
35273
+ };
35289
35274
  }
35290
35275
  // TODO: [🕛] Unite `AgentBasicInformation`, `ChatParticipant`, `LlmExecutionTools` + `LlmToolsMetadata`
35291
35276