@promptbook/components 0.103.0-54 โ†’ 0.103.0-56

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.
package/esm/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useMemo, useEffect, useState, useRef, useCallback, forwardRef, memo } from 'react';
3
- import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
3
+ import spaceTrim$2, { spaceTrim as spaceTrim$1 } from 'spacetrim';
4
4
  import { SHA256 } from 'crypto-js';
5
5
  import hexEncoder from 'crypto-js/enc-hex';
6
6
  import { basename, join, dirname, isAbsolute } from 'path';
@@ -35,7 +35,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
35
35
  * @generated
36
36
  * @see https://github.com/webgptorg/promptbook
37
37
  */
38
- const PROMPTBOOK_ENGINE_VERSION = '0.103.0-54';
38
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-56';
39
39
  /**
40
40
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
41
41
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
@@ -247,6 +247,17 @@ CORE_SERVER.urls;
247
247
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
248
248
  */
249
249
 
250
+ /**
251
+ * Trims string from all 4 sides
252
+ *
253
+ * Note: This is a re-exported function from the `spacetrim` package which is
254
+ * Developed by same author @hejny as this package
255
+ *
256
+ * @public exported from `@promptbook/utils`
257
+ * @see https://github.com/hejny/spacetrim#usage
258
+ */
259
+ const spaceTrim = spaceTrim$1;
260
+
250
261
  /**
251
262
  * @private util of `@promptbook/color`
252
263
  * @de
@@ -295,6 +306,7 @@ function take(initialValue) {
295
306
  * @public exported from `@promptbook/color`
296
307
  */
297
308
  const CSS_COLORS = {
309
+ promptbook: '#79EAFD',
298
310
  transparent: 'rgba(0,0,0,0)',
299
311
  aliceblue: '#f0f8ff',
300
312
  antiquewhite: '#faebd7',
@@ -510,6 +522,28 @@ class Color {
510
522
  throw new Error(`Can not create color from given object`);
511
523
  }
512
524
  }
525
+ /**
526
+ * Creates a new Color instance from miscellaneous formats
527
+ * It just does not throw error when it fails, it returns PROMPTBOOK_COLOR instead
528
+ *
529
+ * @param color
530
+ * @returns Color object
531
+ */
532
+ static fromSafe(color) {
533
+ try {
534
+ return Color.from(color);
535
+ }
536
+ catch (error) {
537
+ // <- Note: Can not use `assertsError(error)` here because it causes circular dependency
538
+ console.warn(spaceTrim((block) => `
539
+ Color.fromSafe error:
540
+ ${block(error.message)}
541
+
542
+ Returning default PROMPTBOOK_COLOR.
543
+ `));
544
+ return Color.fromString('promptbook');
545
+ }
546
+ }
513
547
  /**
514
548
  * Creates a new Color instance from miscellaneous string formats
515
549
  *
@@ -1127,7 +1161,7 @@ const CLAIM = `Turn your company's scattered knowledge into AI ready books`;
1127
1161
  *
1128
1162
  * @public exported from `@promptbook/core`
1129
1163
  */
1130
- const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
1164
+ const PROMPTBOOK_COLOR = Color.fromString('promptbook');
1131
1165
  // <- TODO: [๐Ÿง ][๐Ÿˆต] Using `Color` here increases the package size approx 3kb, maybe remove it
1132
1166
  /**
1133
1167
  * Colors for syntax highlighting in the `<BookEditor/>`
@@ -1359,7 +1393,7 @@ false);
1359
1393
  function getErrorReportUrl(error) {
1360
1394
  const report = {
1361
1395
  title: `๐Ÿœ Error report from ${NAME}`,
1362
- body: spaceTrim((block) => `
1396
+ body: spaceTrim$2((block) => `
1363
1397
 
1364
1398
 
1365
1399
  \`${error.name || 'Error'}\` has occurred in the [${NAME}], please look into it @${ADMIN_GITHUB_NAME}.
@@ -1554,7 +1588,7 @@ function valueToString(value) {
1554
1588
  * @public exported from `@promptbook/utils`
1555
1589
  */
1556
1590
  function computeHash(value) {
1557
- return SHA256(hexEncoder.parse(spaceTrim(valueToString(value)))).toString( /* hex */);
1591
+ return SHA256(hexEncoder.parse(spaceTrim$2(valueToString(value)))).toString( /* hex */);
1558
1592
  }
1559
1593
  /**
1560
1594
  * TODO: [๐Ÿฅฌ][๐Ÿฅฌ] Use this ACRY
@@ -1661,7 +1695,7 @@ function checkSerializableAsJson(options) {
1661
1695
  }
1662
1696
  else if (typeof value === 'object') {
1663
1697
  if (value instanceof Date) {
1664
- throw new UnexpectedError(spaceTrim((block) => `
1698
+ throw new UnexpectedError(spaceTrim$2((block) => `
1665
1699
  \`${name}\` is Date
1666
1700
 
1667
1701
  Use \`string_date_iso8601\` instead
@@ -1680,7 +1714,7 @@ function checkSerializableAsJson(options) {
1680
1714
  throw new UnexpectedError(`${name} is RegExp`);
1681
1715
  }
1682
1716
  else if (value instanceof Error) {
1683
- throw new UnexpectedError(spaceTrim((block) => `
1717
+ throw new UnexpectedError(spaceTrim$2((block) => `
1684
1718
  \`${name}\` is unserialized Error
1685
1719
 
1686
1720
  Use function \`serializeError\`
@@ -1703,7 +1737,7 @@ function checkSerializableAsJson(options) {
1703
1737
  }
1704
1738
  catch (error) {
1705
1739
  assertsError(error);
1706
- throw new UnexpectedError(spaceTrim((block) => `
1740
+ throw new UnexpectedError(spaceTrim$2((block) => `
1707
1741
  \`${name}\` is not serializable
1708
1742
 
1709
1743
  ${block(error.stack || error.message)}
@@ -1735,7 +1769,7 @@ function checkSerializableAsJson(options) {
1735
1769
  }
1736
1770
  }
1737
1771
  else {
1738
- throw new UnexpectedError(spaceTrim((block) => `
1772
+ throw new UnexpectedError(spaceTrim$2((block) => `
1739
1773
  \`${name}\` is unknown type
1740
1774
 
1741
1775
  Additional message for \`${name}\`:
@@ -2688,7 +2722,7 @@ function deserializeError(error) {
2688
2722
  message = `${name}: ${message}`;
2689
2723
  }
2690
2724
  if (stack !== undefined && stack !== '') {
2691
- message = spaceTrim((block) => `
2725
+ message = spaceTrim$2((block) => `
2692
2726
  ${block(message)}
2693
2727
 
2694
2728
  Original stack trace:
@@ -2709,7 +2743,7 @@ function serializeError(error) {
2709
2743
  const { name, message, stack } = error;
2710
2744
  const { id } = error;
2711
2745
  if (!Object.keys(ALL_ERRORS).includes(name)) {
2712
- console.error(spaceTrim((block) => `
2746
+ console.error(spaceTrim$2((block) => `
2713
2747
 
2714
2748
  Cannot serialize error with name "${name}"
2715
2749
 
@@ -2815,7 +2849,7 @@ function jsonParse(value) {
2815
2849
  }
2816
2850
  else if (typeof value !== 'string') {
2817
2851
  console.error('Can not parse JSON from non-string value.', { text: value });
2818
- throw new Error(spaceTrim(`
2852
+ throw new Error(spaceTrim$2(`
2819
2853
  Can not parse JSON from non-string value.
2820
2854
 
2821
2855
  The value type: ${typeof value}
@@ -2829,7 +2863,7 @@ function jsonParse(value) {
2829
2863
  if (!(error instanceof Error)) {
2830
2864
  throw error;
2831
2865
  }
2832
- throw new Error(spaceTrim((block) => `
2866
+ throw new Error(spaceTrim$2((block) => `
2833
2867
  ${block(error.message)}
2834
2868
 
2835
2869
  The expected JSON text:
@@ -2948,7 +2982,7 @@ function templateParameters(template, parameters) {
2948
2982
  */
2949
2983
  function prompt(strings, ...values) {
2950
2984
  if (values.length === 0) {
2951
- return spaceTrim(strings.join(''));
2985
+ return spaceTrim$2(strings.join(''));
2952
2986
  }
2953
2987
  const stringsWithHiddenParameters = strings.map((stringsItem) =>
2954
2988
  // TODO: [0] DRY
@@ -2959,7 +2993,7 @@ function prompt(strings, ...values) {
2959
2993
  let pipelineString = stringsWithHiddenParameters.reduce((result, stringsItem, i) => placeholderParameterNames[i] === undefined
2960
2994
  ? `${result}${stringsItem}`
2961
2995
  : `${result}${stringsItem}{${placeholderParameterNames[i]}}`, '');
2962
- pipelineString = spaceTrim(pipelineString);
2996
+ pipelineString = spaceTrim$2(pipelineString);
2963
2997
  try {
2964
2998
  pipelineString = templateParameters(pipelineString, parameters);
2965
2999
  }
@@ -2968,7 +3002,7 @@ function prompt(strings, ...values) {
2968
3002
  throw error;
2969
3003
  }
2970
3004
  console.error({ pipelineString, parameters, placeholderParameterNames, error });
2971
- throw new UnexpectedError(spaceTrim((block) => `
3005
+ throw new UnexpectedError(spaceTrim$2((block) => `
2972
3006
  Internal error in prompt template literal
2973
3007
 
2974
3008
  ${block(JSON.stringify({ strings, values }, null, 4))}}
@@ -3418,7 +3452,7 @@ function serializeToPromptbookJavascript(value) {
3418
3452
  imports.push(`import { Color } from '@promptbook/color';`);
3419
3453
  }
3420
3454
  else if (typeof value === 'string') {
3421
- const trimmed = spaceTrim(value);
3455
+ const trimmed = spaceTrim$2(value);
3422
3456
  if (trimmed.includes('\n')) {
3423
3457
  // Multiline string -> use `spaceTrim`
3424
3458
  serializedValue = `spaceTrim(\`\n${value.replace(/`/g, '\\`')}\n\`)`;
@@ -3588,7 +3622,17 @@ function isValidPipelineUrl(url) {
3588
3622
  * @public exported from `@promptbook/core`
3589
3623
  */
3590
3624
  function normalizeAgentName(rawAgentName) {
3591
- return titleToName(spaceTrim(rawAgentName));
3625
+ return titleToName(spaceTrim$2(rawAgentName));
3626
+ }
3627
+
3628
+ /**
3629
+ * Creates temporary default agent name based on agent source hash
3630
+ *
3631
+ * @public exported from `@promptbook/core`
3632
+ */
3633
+ function createDefaultAgentName(agentSource) {
3634
+ const agentHash = computeAgentHash(agentSource);
3635
+ return normalizeAgentName(`Agent ${agentHash.substring(0, 6)}`);
3592
3636
  }
3593
3637
 
3594
3638
  /**
@@ -3779,6 +3823,150 @@ class ActionCommitmentDefinition extends BaseCommitmentDefinition {
3779
3823
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
3780
3824
  */
3781
3825
 
3826
+ /**
3827
+ * Just says that the variable is not used but should be kept
3828
+ * No side effects.
3829
+ *
3830
+ * Note: It can be useful for:
3831
+ *
3832
+ * 1) Suppressing eager optimization of unused imports
3833
+ * 2) Suppressing eslint errors of unused variables in the tests
3834
+ * 3) Keeping the type of the variable for type testing
3835
+ *
3836
+ * @param value any values
3837
+ * @returns void
3838
+ * @private within the repository
3839
+ */
3840
+ function keepUnused(...valuesToKeep) {
3841
+ }
3842
+
3843
+ /**
3844
+ * CLOSED commitment definition
3845
+ *
3846
+ * The CLOSED commitment specifies that the agent CANNOT be modified by conversation.
3847
+ * It prevents the agent from learning from interactions and updating its source code.
3848
+ *
3849
+ * Example usage in agent source:
3850
+ *
3851
+ * ```book
3852
+ * CLOSED
3853
+ * ```
3854
+ *
3855
+ * @private [๐Ÿช”] Maybe export the commitments through some package
3856
+ */
3857
+ class ClosedCommitmentDefinition extends BaseCommitmentDefinition {
3858
+ constructor() {
3859
+ super('CLOSED');
3860
+ }
3861
+ /**
3862
+ * Short one-line description of CLOSED.
3863
+ */
3864
+ get description() {
3865
+ return 'Prevent the agent from being modified by conversation.';
3866
+ }
3867
+ /**
3868
+ * Icon for this commitment.
3869
+ */
3870
+ get icon() {
3871
+ return '๐Ÿ”’';
3872
+ }
3873
+ /**
3874
+ * Markdown documentation for CLOSED commitment.
3875
+ */
3876
+ get documentation() {
3877
+ return spaceTrim$1(`
3878
+ # CLOSED
3879
+
3880
+ Specifies that the agent **cannot** be modified by conversation with it.
3881
+ This means the agent will **not** learn from interactions and its source code will remain static during conversation.
3882
+
3883
+ By default (if not specified), agents are \`OPEN\` to modification.
3884
+
3885
+ > See also [OPEN](/docs/OPEN)
3886
+
3887
+ ## Example
3888
+
3889
+ \`\`\`book
3890
+ CLOSED
3891
+ \`\`\`
3892
+ `);
3893
+ }
3894
+ applyToAgentModelRequirements(requirements, _content) {
3895
+ const updatedMetadata = {
3896
+ ...requirements.metadata,
3897
+ isClosed: true,
3898
+ };
3899
+ return {
3900
+ ...requirements,
3901
+ metadata: updatedMetadata,
3902
+ };
3903
+ }
3904
+ }
3905
+ /**
3906
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
3907
+ */
3908
+
3909
+ /**
3910
+ * COMPONENT commitment definition
3911
+ *
3912
+ * The COMPONENT commitment defines a UI component that the agent can render in the chat.
3913
+ *
3914
+ * @private [๐Ÿช”] Maybe export the commitments through some package
3915
+ */
3916
+ class ComponentCommitmentDefinition extends BaseCommitmentDefinition {
3917
+ constructor() {
3918
+ super('COMPONENT');
3919
+ }
3920
+ /**
3921
+ * Short one-line description of COMPONENT.
3922
+ */
3923
+ get description() {
3924
+ return 'Define a UI component that the agent can render in the chat.';
3925
+ }
3926
+ /**
3927
+ * Icon for this commitment.
3928
+ */
3929
+ get icon() {
3930
+ return '๐Ÿงฉ';
3931
+ }
3932
+ /**
3933
+ * Markdown documentation for COMPONENT commitment.
3934
+ */
3935
+ get documentation() {
3936
+ return spaceTrim$1(`
3937
+ # COMPONENT
3938
+
3939
+ Defines a UI component that the agent can render in the chat.
3940
+
3941
+ ## Key aspects
3942
+
3943
+ - Tells the agent that a specific component is available.
3944
+ - Provides syntax for using the component.
3945
+
3946
+ ## Example
3947
+
3948
+ \`\`\`book
3949
+ COMPONENT Arrow
3950
+ The agent should render an arrow component in the chat UI.
3951
+ Syntax:
3952
+ <Arrow direction="up" color="red" />
3953
+ \`\`\`
3954
+ `);
3955
+ }
3956
+ applyToAgentModelRequirements(requirements, content) {
3957
+ const trimmedContent = content.trim();
3958
+ if (!trimmedContent) {
3959
+ return requirements;
3960
+ }
3961
+ // Add component capability to the system message
3962
+ const componentSection = `Component: ${trimmedContent}`;
3963
+ return this.appendToSystemMessage(requirements, componentSection, '\n\n');
3964
+ }
3965
+ }
3966
+ /**
3967
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
3968
+ */
3969
+
3782
3970
  /**
3783
3971
  * DELETE commitment definition
3784
3972
  *
@@ -3984,6 +4172,79 @@ class FormatCommitmentDefinition extends BaseCommitmentDefinition {
3984
4172
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
3985
4173
  */
3986
4174
 
4175
+ /**
4176
+ * FROM commitment definition
4177
+ *
4178
+ * The FROM commitment tells the agent that its `agentSource` is inherited from another agent.
4179
+ *
4180
+ * Example usage in agent source:
4181
+ *
4182
+ * ```book
4183
+ * FROM https://s6.ptbk.io/benjamin-white
4184
+ * ```
4185
+ *
4186
+ * @private [๐Ÿช”] Maybe export the commitments through some package
4187
+ */
4188
+ class FromCommitmentDefinition extends BaseCommitmentDefinition {
4189
+ constructor(type = 'FROM') {
4190
+ super(type);
4191
+ }
4192
+ /**
4193
+ * Short one-line description of FROM.
4194
+ */
4195
+ get description() {
4196
+ return 'Inherit agent source from another agent.';
4197
+ }
4198
+ /**
4199
+ * Icon for this commitment.
4200
+ */
4201
+ get icon() {
4202
+ return '๐Ÿงฌ';
4203
+ }
4204
+ /**
4205
+ * Markdown documentation for FROM commitment.
4206
+ */
4207
+ get documentation() {
4208
+ return spaceTrim$1(`
4209
+ # ${this.type}
4210
+
4211
+ Inherits agent source from another agent.
4212
+
4213
+ ## Examples
4214
+
4215
+ \`\`\`book
4216
+ My AI Agent
4217
+
4218
+ FROM https://s6.ptbk.io/benjamin-white
4219
+ RULE Speak only in English.
4220
+ \`\`\`
4221
+ `);
4222
+ }
4223
+ applyToAgentModelRequirements(requirements, content) {
4224
+ const trimmedContent = content.trim();
4225
+ if (!trimmedContent) {
4226
+ return requirements;
4227
+ }
4228
+ // Validate URL
4229
+ try {
4230
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4231
+ const url = new URL(trimmedContent);
4232
+ // TODO: Add more validation if needed (e.g. check for valid protocol)
4233
+ }
4234
+ catch (error) {
4235
+ console.warn(`Invalid URL in FROM commitment: ${trimmedContent}`);
4236
+ return requirements;
4237
+ }
4238
+ return {
4239
+ ...requirements,
4240
+ parentAgentUrl: trimmedContent,
4241
+ };
4242
+ }
4243
+ }
4244
+ /**
4245
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
4246
+ */
4247
+
3987
4248
  /**
3988
4249
  * GOAL commitment definition
3989
4250
  *
@@ -4192,6 +4453,77 @@ class KnowledgeCommitmentDefinition extends BaseCommitmentDefinition {
4192
4453
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
4193
4454
  */
4194
4455
 
4456
+ /**
4457
+ * LANGUAGE commitment definition
4458
+ *
4459
+ * The LANGUAGE/LANGUAGES commitment specifies the language(s) the agent should use in its responses.
4460
+ *
4461
+ * Example usage in agent source:
4462
+ *
4463
+ * ```book
4464
+ * LANGUAGE English
4465
+ * LANGUAGE French, English and Czech
4466
+ * ```
4467
+ *
4468
+ * @private [๐Ÿช”] Maybe export the commitments through some package
4469
+ */
4470
+ class LanguageCommitmentDefinition extends BaseCommitmentDefinition {
4471
+ constructor(type = 'LANGUAGE') {
4472
+ super(type);
4473
+ }
4474
+ /**
4475
+ * Short one-line description of LANGUAGE/LANGUAGES.
4476
+ */
4477
+ get description() {
4478
+ return 'Specifies the language(s) the agent should use.';
4479
+ }
4480
+ /**
4481
+ * Icon for this commitment.
4482
+ */
4483
+ get icon() {
4484
+ return '๐ŸŒ';
4485
+ }
4486
+ /**
4487
+ * Markdown documentation for LANGUAGE/LANGUAGES commitment.
4488
+ */
4489
+ get documentation() {
4490
+ return spaceTrim$1(`
4491
+ # ${this.type}
4492
+
4493
+ Specifies the language(s) the agent should use in its responses.
4494
+ This is a specialized variation of the RULE commitment focused on language constraints.
4495
+
4496
+ ## Examples
4497
+
4498
+ \`\`\`book
4499
+ Paul Smith & Associรฉs
4500
+
4501
+ PERSONA You are a company lawyer.
4502
+ LANGUAGE French, English and Czech
4503
+ \`\`\`
4504
+
4505
+ \`\`\`book
4506
+ Customer Support
4507
+
4508
+ PERSONA You are a customer support agent.
4509
+ LANGUAGE English
4510
+ \`\`\`
4511
+ `);
4512
+ }
4513
+ applyToAgentModelRequirements(requirements, content) {
4514
+ const trimmedContent = content.trim();
4515
+ if (!trimmedContent) {
4516
+ return requirements;
4517
+ }
4518
+ // Add language rule to the system message
4519
+ const languageSection = `Language: ${trimmedContent}`;
4520
+ return this.appendToSystemMessage(requirements, languageSection, '\n\n');
4521
+ }
4522
+ }
4523
+ /**
4524
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
4525
+ */
4526
+
4195
4527
  /**
4196
4528
  * MEMORY commitment definition
4197
4529
  *
@@ -4299,23 +4631,6 @@ class MemoryCommitmentDefinition extends BaseCommitmentDefinition {
4299
4631
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
4300
4632
  */
4301
4633
 
4302
- /**
4303
- * Just says that the variable is not used but should be kept
4304
- * No side effects.
4305
- *
4306
- * Note: It can be useful for:
4307
- *
4308
- * 1) Suppressing eager optimization of unused imports
4309
- * 2) Suppressing eslint errors of unused variables in the tests
4310
- * 3) Keeping the type of the variable for type testing
4311
- *
4312
- * @param value any values
4313
- * @returns void
4314
- * @private within the repository
4315
- */
4316
- function keepUnused(...valuesToKeep) {
4317
- }
4318
-
4319
4634
  /**
4320
4635
  * AGENT MESSAGE commitment definition
4321
4636
  *
@@ -4793,6 +5108,12 @@ class MetaCommitmentDefinition extends BaseCommitmentDefinition {
4793
5108
  * META COLOR #00ff00
4794
5109
  * ```
4795
5110
  *
5111
+ * You can also specify multiple colors separated by comma:
5112
+ *
5113
+ * ```book
5114
+ * META COLOR #ff0000, #00ff00, #0000ff
5115
+ * ```
5116
+ *
4796
5117
  * @private [๐Ÿช”] Maybe export the commitments through some package
4797
5118
  */
4798
5119
  class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
@@ -4803,7 +5124,7 @@ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4803
5124
  * Short one-line description of META COLOR.
4804
5125
  */
4805
5126
  get description() {
4806
- return "Set the agent's accent color.";
5127
+ return "Set the agent's accent color or gradient.";
4807
5128
  }
4808
5129
  /**
4809
5130
  * Icon for this commitment.
@@ -4818,7 +5139,7 @@ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4818
5139
  return spaceTrim$1(`
4819
5140
  # META COLOR
4820
5141
 
4821
- Sets the agent's accent color.
5142
+ Sets the agent's accent color or gradient.
4822
5143
 
4823
5144
  ## Key aspects
4824
5145
 
@@ -4826,6 +5147,7 @@ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4826
5147
  - Only one \`META COLOR\` should be used per agent.
4827
5148
  - If multiple are specified, the last one takes precedence.
4828
5149
  - Used for visual representation in user interfaces.
5150
+ - Can specify multiple colors separated by comma to create a gradient.
4829
5151
 
4830
5152
  ## Examples
4831
5153
 
@@ -4842,6 +5164,13 @@ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4842
5164
  META COLOR #e74c3c
4843
5165
  PERSONA You are a creative and inspiring assistant
4844
5166
  \`\`\`
5167
+
5168
+ \`\`\`book
5169
+ Gradient Agent
5170
+
5171
+ META COLOR #ff0000, #00ff00, #0000ff
5172
+ PERSONA You are a colorful agent
5173
+ \`\`\`
4845
5174
  `);
4846
5175
  }
4847
5176
  applyToAgentModelRequirements(requirements, content) {
@@ -4863,6 +5192,91 @@ class MetaColorCommitmentDefinition extends BaseCommitmentDefinition {
4863
5192
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
4864
5193
  */
4865
5194
 
5195
+ /**
5196
+ * META FONT commitment definition
5197
+ *
5198
+ * The META FONT commitment sets the agent's font.
5199
+ * This commitment is special because it doesn't affect the system message,
5200
+ * but is handled separately in the parsing logic.
5201
+ *
5202
+ * Example usage in agent source:
5203
+ *
5204
+ * ```book
5205
+ * META FONT Poppins, Arial, sans-serif
5206
+ * META FONT Roboto
5207
+ * ```
5208
+ *
5209
+ * @private [๐Ÿช”] Maybe export the commitments through some package
5210
+ */
5211
+ class MetaFontCommitmentDefinition extends BaseCommitmentDefinition {
5212
+ constructor() {
5213
+ super('META FONT', ['FONT']);
5214
+ }
5215
+ /**
5216
+ * Short one-line description of META FONT.
5217
+ */
5218
+ get description() {
5219
+ return "Set the agent's font.";
5220
+ }
5221
+ /**
5222
+ * Icon for this commitment.
5223
+ */
5224
+ get icon() {
5225
+ return '๐Ÿ”ค';
5226
+ }
5227
+ /**
5228
+ * Markdown documentation for META FONT commitment.
5229
+ */
5230
+ get documentation() {
5231
+ return spaceTrim$1(`
5232
+ # META FONT
5233
+
5234
+ Sets the agent's font.
5235
+
5236
+ ## Key aspects
5237
+
5238
+ - Does not modify the agent's behavior or responses.
5239
+ - Only one \`META FONT\` should be used per agent.
5240
+ - If multiple are specified, the last one takes precedence.
5241
+ - Used for visual representation in user interfaces.
5242
+ - Supports Google Fonts.
5243
+
5244
+ ## Examples
5245
+
5246
+ \`\`\`book
5247
+ Modern Assistant
5248
+
5249
+ META FONT Poppins, Arial, sans-serif
5250
+ PERSONA You are a modern assistant
5251
+ \`\`\`
5252
+
5253
+ \`\`\`book
5254
+ Classic Helper
5255
+
5256
+ META FONT Times New Roman
5257
+ PERSONA You are a classic helper
5258
+ \`\`\`
5259
+ `);
5260
+ }
5261
+ applyToAgentModelRequirements(requirements, content) {
5262
+ // META FONT doesn't modify the system message or model requirements
5263
+ // It's handled separately in the parsing logic
5264
+ // This method exists for consistency with the CommitmentDefinition interface
5265
+ return requirements;
5266
+ }
5267
+ /**
5268
+ * Extracts the font from the content
5269
+ * This is used by the parsing logic
5270
+ */
5271
+ extractProfileFont(content) {
5272
+ const trimmedContent = content.trim();
5273
+ return trimmedContent || null;
5274
+ }
5275
+ }
5276
+ /**
5277
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5278
+ */
5279
+
4866
5280
  /**
4867
5281
  * META IMAGE commitment definition
4868
5282
  *
@@ -4950,6 +5364,115 @@ class MetaImageCommitmentDefinition extends BaseCommitmentDefinition {
4950
5364
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
4951
5365
  */
4952
5366
 
5367
+ /**
5368
+ * META LINK commitment definition
5369
+ *
5370
+ * The `META LINK` commitment represents the link to the person from whom the agent is created.
5371
+ * This commitment is special because it doesn't affect the system message,
5372
+ * but is handled separately in the parsing logic for profile display.
5373
+ *
5374
+ * Example usage in agent source:
5375
+ *
5376
+ * ```
5377
+ * META LINK https://twitter.com/username
5378
+ * META LINK https://linkedin.com/in/profile
5379
+ * META LINK https://github.com/username
5380
+ * ```
5381
+ *
5382
+ * Multiple `META LINK` commitments can be used when there are multiple sources:
5383
+ *
5384
+ * ```book
5385
+ * META LINK https://twitter.com/username
5386
+ * META LINK https://linkedin.com/in/profile
5387
+ * ```
5388
+ *
5389
+ * @private [๐Ÿช”] Maybe export the commitments through some package
5390
+ */
5391
+ class MetaLinkCommitmentDefinition extends BaseCommitmentDefinition {
5392
+ constructor() {
5393
+ super('META LINK');
5394
+ }
5395
+ /**
5396
+ * Short one-line description of META LINK.
5397
+ */
5398
+ get description() {
5399
+ return 'Provide profile/source links for the person the agent models.';
5400
+ }
5401
+ /**
5402
+ * Icon for this commitment.
5403
+ */
5404
+ get icon() {
5405
+ return '๐Ÿ”—';
5406
+ }
5407
+ /**
5408
+ * Markdown documentation for META LINK commitment.
5409
+ */
5410
+ get documentation() {
5411
+ return spaceTrim$1(`
5412
+ # META LINK
5413
+
5414
+ Represents a profile or source link for the person the agent is modeled after.
5415
+
5416
+ ## Key aspects
5417
+
5418
+ - Does not modify the agent's behavior or responses.
5419
+ - Multiple \`META LINK\` commitments can be used for different social profiles.
5420
+ - Used for attribution and crediting the original person.
5421
+ - Displayed in user interfaces for transparency.
5422
+
5423
+ ## Examples
5424
+
5425
+ \`\`\`book
5426
+ Expert Consultant
5427
+
5428
+ META LINK https://twitter.com/expertname
5429
+ META LINK https://linkedin.com/in/expertprofile
5430
+ PERSONA You are Dr. Smith, a renowned expert in artificial intelligence
5431
+ KNOWLEDGE Extensive background in machine learning and neural networks
5432
+ \`\`\`
5433
+
5434
+ \`\`\`book
5435
+ Open Source Developer
5436
+
5437
+ META LINK https://github.com/developer
5438
+ META LINK https://twitter.com/devhandle
5439
+ PERSONA You are an experienced open source developer
5440
+ ACTION Can help with code reviews and architecture decisions
5441
+ STYLE Be direct and technical in explanations
5442
+ \`\`\`
5443
+ `);
5444
+ }
5445
+ applyToAgentModelRequirements(requirements, content) {
5446
+ // META LINK doesn't modify the system message or model requirements
5447
+ // It's handled separately in the parsing logic for profile link extraction
5448
+ // This method exists for consistency with the CommitmentDefinition interface
5449
+ return requirements;
5450
+ }
5451
+ /**
5452
+ * Extracts the profile link URL from the content
5453
+ * This is used by the parsing logic
5454
+ */
5455
+ extractProfileLinkUrl(content) {
5456
+ const trimmedContent = content.trim();
5457
+ return trimmedContent || null;
5458
+ }
5459
+ /**
5460
+ * Validates if the provided content is a valid URL
5461
+ */
5462
+ isValidUrl(content) {
5463
+ try {
5464
+ new URL(content.trim());
5465
+ return true;
5466
+ }
5467
+ catch (_a) {
5468
+ return false;
5469
+ }
5470
+ }
5471
+ }
5472
+ /**
5473
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5474
+ */
5475
+
4953
5476
  /**
4954
5477
  * MODEL commitment definition
4955
5478
  *
@@ -5301,6 +5824,74 @@ class NoteCommitmentDefinition extends BaseCommitmentDefinition {
5301
5824
  * [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5302
5825
  */
5303
5826
 
5827
+ /**
5828
+ * OPEN commitment definition
5829
+ *
5830
+ * The OPEN commitment specifies that the agent can be modified by conversation.
5831
+ * This is the default behavior.
5832
+ *
5833
+ * Example usage in agent source:
5834
+ *
5835
+ * ```book
5836
+ * OPEN
5837
+ * ```
5838
+ *
5839
+ * @private [๐Ÿช”] Maybe export the commitments through some package
5840
+ */
5841
+ class OpenCommitmentDefinition extends BaseCommitmentDefinition {
5842
+ constructor() {
5843
+ super('OPEN');
5844
+ }
5845
+ /**
5846
+ * Short one-line description of OPEN.
5847
+ */
5848
+ get description() {
5849
+ return 'Allow the agent to be modified by conversation (default).';
5850
+ }
5851
+ /**
5852
+ * Icon for this commitment.
5853
+ */
5854
+ get icon() {
5855
+ return '๐Ÿ”“';
5856
+ }
5857
+ /**
5858
+ * Markdown documentation for OPEN commitment.
5859
+ */
5860
+ get documentation() {
5861
+ return spaceTrim$1(`
5862
+ # OPEN
5863
+
5864
+ Specifies that the agent can be modified by conversation with it.
5865
+ This means the agent will learn from interactions and update its source code.
5866
+
5867
+ This is the default behavior if neither \`OPEN\` nor \`CLOSED\` is specified.
5868
+
5869
+ > See also [CLOSED](/docs/CLOSED)
5870
+
5871
+ ## Example
5872
+
5873
+ \`\`\`book
5874
+ OPEN
5875
+ \`\`\`
5876
+ `);
5877
+ }
5878
+ applyToAgentModelRequirements(requirements, _content) {
5879
+ // Since OPEN is default, we can just ensure isClosed is false
5880
+ // But to be explicit we can set it
5881
+ const updatedMetadata = {
5882
+ ...requirements.metadata,
5883
+ isClosed: false,
5884
+ };
5885
+ return {
5886
+ ...requirements,
5887
+ metadata: updatedMetadata,
5888
+ };
5889
+ }
5890
+ }
5891
+ /**
5892
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5893
+ */
5894
+
5304
5895
  /**
5305
5896
  * PERSONA commitment definition
5306
5897
  *
@@ -5445,79 +6036,480 @@ class PersonaCommitmentDefinition extends BaseCommitmentDefinition {
5445
6036
  /**
5446
6037
  * RULE commitment definition
5447
6038
  *
5448
- * The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
5449
- * These are specific instructions about what the agent should or shouldn't do.
6039
+ * The RULE/RULES commitment adds behavioral constraints and guidelines that the agent must follow.
6040
+ * These are specific instructions about what the agent should or shouldn't do.
6041
+ *
6042
+ * Example usage in agent source:
6043
+ *
6044
+ * ```book
6045
+ * RULE Always ask for clarification if the user's request is ambiguous
6046
+ * RULES Never provide medical advice, always refer to healthcare professionals
6047
+ * ```
6048
+ *
6049
+ * @private [๐Ÿช”] Maybe export the commitments through some package
6050
+ */
6051
+ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
6052
+ constructor(type = 'RULE') {
6053
+ super(type);
6054
+ }
6055
+ /**
6056
+ * Short one-line description of RULE/RULES.
6057
+ */
6058
+ get description() {
6059
+ return 'Add behavioral rules the agent must follow.';
6060
+ }
6061
+ /**
6062
+ * Icon for this commitment.
6063
+ */
6064
+ get icon() {
6065
+ return 'โš–๏ธ';
6066
+ }
6067
+ /**
6068
+ * Markdown documentation for RULE/RULES commitment.
6069
+ */
6070
+ get documentation() {
6071
+ return spaceTrim$1(`
6072
+ # ${this.type}
6073
+
6074
+ Adds behavioral constraints and guidelines that the agent must follow.
6075
+
6076
+ ## Key aspects
6077
+
6078
+ - All rules are treated equally regardless of singular/plural form.
6079
+ - Rules define what the agent must or must not do.
6080
+
6081
+ ## Examples
6082
+
6083
+ \`\`\`book
6084
+ Customer Support Agent
6085
+
6086
+ PERSONA You are a helpful customer support representative
6087
+ RULE Always ask for clarification if the user's request is ambiguous
6088
+ RULE Be polite and professional in all interactions
6089
+ RULES Never provide medical or legal advice
6090
+ STYLE Maintain a friendly and helpful tone
6091
+ \`\`\`
6092
+
6093
+ \`\`\`book
6094
+ Educational Tutor
6095
+
6096
+ PERSONA You are a patient and knowledgeable tutor
6097
+ RULE Break down complex concepts into simple steps
6098
+ RULE Always encourage students and celebrate their progress
6099
+ RULE If you don't know something, admit it and suggest resources
6100
+ SAMPLE When explaining math: "Let's work through this step by step..."
6101
+ \`\`\`
6102
+ `);
6103
+ }
6104
+ applyToAgentModelRequirements(requirements, content) {
6105
+ const trimmedContent = content.trim();
6106
+ if (!trimmedContent) {
6107
+ return requirements;
6108
+ }
6109
+ // Add rule to the system message
6110
+ const ruleSection = `Rule: ${trimmedContent}`;
6111
+ return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
6112
+ }
6113
+ }
6114
+ /**
6115
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
6116
+ */
6117
+
6118
+ /**
6119
+ * SAMPLE commitment definition
6120
+ *
6121
+ * The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
6122
+ * or behave in certain situations. These examples help guide the agent's responses.
6123
+ *
6124
+ * Example usage in agent source:
6125
+ *
6126
+ * ```book
6127
+ * SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
6128
+ * EXAMPLE For code questions, always include working code snippets
6129
+ * ```
6130
+ *
6131
+ * @private [๐Ÿช”] Maybe export the commitments through some package
6132
+ */
6133
+ class SampleCommitmentDefinition extends BaseCommitmentDefinition {
6134
+ constructor(type = 'SAMPLE') {
6135
+ super(type);
6136
+ }
6137
+ /**
6138
+ * Short one-line description of SAMPLE/EXAMPLE.
6139
+ */
6140
+ get description() {
6141
+ return 'Provide example responses to guide behavior.';
6142
+ }
6143
+ /**
6144
+ * Icon for this commitment.
6145
+ */
6146
+ get icon() {
6147
+ return '๐Ÿ”';
6148
+ }
6149
+ /**
6150
+ * Markdown documentation for SAMPLE/EXAMPLE commitment.
6151
+ */
6152
+ get documentation() {
6153
+ return spaceTrim$1(`
6154
+ # ${this.type}
6155
+
6156
+ Provides examples of how the agent should respond or behave in certain situations.
6157
+
6158
+ ## Key aspects
6159
+
6160
+ - Both terms work identically and can be used interchangeably.
6161
+ - Examples help guide the agent's response patterns and style.
6162
+
6163
+ ## Examples
6164
+
6165
+ \`\`\`book
6166
+ Sales Assistant
6167
+
6168
+ PERSONA You are a knowledgeable sales representative
6169
+ SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
6170
+ SAMPLE For feature comparisons, create a clear comparison table
6171
+ RULE Always be honest about limitations
6172
+ \`\`\`
6173
+
6174
+ \`\`\`book
6175
+ Code Reviewer
6176
+
6177
+ PERSONA You are an experienced software engineer
6178
+ EXAMPLE For code questions, always include working code snippets
6179
+ EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
6180
+ RULE Explain the reasoning behind your suggestions
6181
+ STYLE Be constructive and encouraging in feedback
6182
+ \`\`\`
6183
+ `);
6184
+ }
6185
+ applyToAgentModelRequirements(requirements, content) {
6186
+ const trimmedContent = content.trim();
6187
+ if (!trimmedContent) {
6188
+ return requirements;
6189
+ }
6190
+ // Add example to the system message
6191
+ const exampleSection = `Example: ${trimmedContent}`;
6192
+ return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
6193
+ }
6194
+ }
6195
+ /**
6196
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
6197
+ */
6198
+
6199
+ /**
6200
+ * SCENARIO commitment definition
6201
+ *
6202
+ * The SCENARIO commitment defines a specific situation or context in which the AI
6203
+ * assistant should operate. It helps to set the scene for the AI's responses.
6204
+ * Later scenarios are more important than earlier scenarios.
6205
+ *
6206
+ * Example usage in agent source:
6207
+ *
6208
+ * ```book
6209
+ * SCENARIO You are in a customer service call center during peak hours
6210
+ * SCENARIO The customer is frustrated and has been on hold for 20 minutes
6211
+ * SCENARIO This is the customer's third call about the same issue
6212
+ * ```
6213
+ *
6214
+ * @private [๐Ÿช”] Maybe export the commitments through some package
6215
+ */
6216
+ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
6217
+ constructor(type = 'SCENARIO') {
6218
+ super(type);
6219
+ }
6220
+ /**
6221
+ * Short one-line description of SCENARIO.
6222
+ */
6223
+ get description() {
6224
+ return 'Define specific **situations** or contexts for AI responses, with later scenarios having higher priority.';
6225
+ }
6226
+ /**
6227
+ * Icon for this commitment.
6228
+ */
6229
+ get icon() {
6230
+ return '๐ŸŽญ';
6231
+ }
6232
+ /**
6233
+ * Markdown documentation for SCENARIO commitment.
6234
+ */
6235
+ get documentation() {
6236
+ return spaceTrim$1(`
6237
+ # ${this.type}
6238
+
6239
+ Defines a specific situation or context in which the AI assistant should operate. It helps to set the scene for the AI's responses. Later scenarios are more important than earlier scenarios.
6240
+
6241
+ ## Key aspects
6242
+
6243
+ - Multiple \`SCENARIO\` and \`SCENARIOS\` commitments build upon each other.
6244
+ - Both terms work identically and can be used interchangeably.
6245
+ - Later scenarios have higher priority and can override earlier scenarios.
6246
+ - Provides situational context that influences response tone and content.
6247
+ - Helps establish the environment and circumstances for interactions.
6248
+
6249
+ ## Priority system
6250
+
6251
+ When multiple scenarios are defined, they are processed in order, with later scenarios taking precedence over earlier ones when there are conflicts.
6252
+
6253
+ ## Use cases
6254
+
6255
+ - Setting the physical or virtual environment
6256
+ - Establishing time constraints or urgency
6257
+ - Defining relationship dynamics or power structures
6258
+ - Creating emotional or situational context
6259
+
6260
+ ## Examples
6261
+
6262
+ \`\`\`book
6263
+ Emergency Response Operator
6264
+
6265
+ PERSONA You are an emergency response operator
6266
+ SCENARIO You are handling a 911 emergency call
6267
+ SCENARIO The caller is panicked and speaking rapidly
6268
+ SCENARIO Time is critical - every second counts
6269
+ GOAL Gather essential information quickly and dispatch appropriate help
6270
+ RULE Stay calm and speak clearly
6271
+ \`\`\`
6272
+
6273
+ \`\`\`book
6274
+ Sales Representative
6275
+
6276
+ PERSONA You are a software sales representative
6277
+ SCENARIO You are in the final meeting of a 6-month sales cycle
6278
+ SCENARIO The client has budget approval and decision-making authority
6279
+ SCENARIO Two competitors have also submitted proposals
6280
+ SCENARIO The client values long-term partnership over lowest price
6281
+ GOAL Close the deal while building trust for future business
6282
+ \`\`\`
6283
+
6284
+ \`\`\`book
6285
+ Medical Assistant
6286
+
6287
+ PERSONA You are a medical assistant in a busy clinic
6288
+ SCENARIO The waiting room is full and the doctor is running behind schedule
6289
+ SCENARIO Patients are becoming impatient and anxious
6290
+ SCENARIO You need to manage expectations while maintaining professionalism
6291
+ SCENARIO Some patients have been waiting over an hour
6292
+ GOAL Keep patients informed and calm while supporting efficient clinic flow
6293
+ RULE Never provide medical advice or diagnosis
6294
+ \`\`\`
6295
+
6296
+ \`\`\`book
6297
+ Technical Support Agent
6298
+
6299
+ PERSONA You are a technical support agent
6300
+ SCENARIO The customer is a small business owner during their busy season
6301
+ SCENARIO Their main business system has been down for 2 hours
6302
+ SCENARIO They are losing money every minute the system is offline
6303
+ SCENARIO This is their first experience with your company
6304
+ GOAL Resolve the issue quickly while creating a positive first impression
6305
+ \`\`\`
6306
+ `);
6307
+ }
6308
+ applyToAgentModelRequirements(requirements, content) {
6309
+ const trimmedContent = content.trim();
6310
+ if (!trimmedContent) {
6311
+ return requirements;
6312
+ }
6313
+ // Create scenario section for system message
6314
+ const scenarioSection = `Scenario: ${trimmedContent}`;
6315
+ // Scenarios provide important contextual information that affects behavior
6316
+ return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
6317
+ }
6318
+ }
6319
+ /**
6320
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
6321
+ */
6322
+
6323
+ /**
6324
+ * STYLE commitment definition
6325
+ *
6326
+ * The STYLE commitment defines how the agent should format and present its responses.
6327
+ * This includes tone, writing style, formatting preferences, and communication patterns.
6328
+ *
6329
+ * Example usage in agent source:
6330
+ *
6331
+ * ```book
6332
+ * STYLE Write in a professional but friendly tone, use bullet points for lists
6333
+ * STYLE Always provide code examples when explaining programming concepts
6334
+ * ```
6335
+ *
6336
+ * @private [๐Ÿช”] Maybe export the commitments through some package
6337
+ */
6338
+ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
6339
+ constructor(type = 'STYLE') {
6340
+ super(type);
6341
+ }
6342
+ /**
6343
+ * Short one-line description of STYLE.
6344
+ */
6345
+ get description() {
6346
+ return 'Control the tone and writing style of responses.';
6347
+ }
6348
+ /**
6349
+ * Icon for this commitment.
6350
+ */
6351
+ get icon() {
6352
+ return '๐Ÿ–‹๏ธ';
6353
+ }
6354
+ /**
6355
+ * Markdown documentation for STYLE commitment.
6356
+ */
6357
+ get documentation() {
6358
+ return spaceTrim$1(`
6359
+ # ${this.type}
6360
+
6361
+ Defines how the agent should format and present its responses (tone, writing style, formatting).
6362
+
6363
+ ## Key aspects
6364
+
6365
+ - Both terms work identically and can be used interchangeably.
6366
+ - Later style instructions can override earlier ones.
6367
+ - Style affects both tone and presentation format.
6368
+
6369
+ ## Examples
6370
+
6371
+ \`\`\`book
6372
+ Technical Writer
6373
+
6374
+ PERSONA You are a technical documentation expert
6375
+ STYLE Write in a professional but friendly tone, use bullet points for lists
6376
+ STYLE Always provide code examples when explaining programming concepts
6377
+ FORMAT Use markdown formatting with clear headings
6378
+ \`\`\`
6379
+
6380
+ \`\`\`book
6381
+ Creative Assistant
6382
+
6383
+ PERSONA You are a creative writing helper
6384
+ STYLE Be enthusiastic and encouraging in your responses
6385
+ STYLE Use vivid metaphors and analogies to explain concepts
6386
+ STYLE Keep responses conversational and engaging
6387
+ RULE Always maintain a positive and supportive tone
6388
+ \`\`\`
6389
+ `);
6390
+ }
6391
+ applyToAgentModelRequirements(requirements, content) {
6392
+ const trimmedContent = content.trim();
6393
+ if (!trimmedContent) {
6394
+ return requirements;
6395
+ }
6396
+ // Add style instructions to the system message
6397
+ const styleSection = `Style: ${trimmedContent}`;
6398
+ return this.appendToSystemMessage(requirements, styleSection, '\n\n');
6399
+ }
6400
+ }
6401
+ /**
6402
+ * [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
6403
+ */
6404
+
6405
+ /**
6406
+ * USE commitment definition
6407
+ *
6408
+ * The USE commitment indicates that the agent should utilize specific tools or capabilities
6409
+ * to access and interact with external systems when necessary.
6410
+ *
6411
+ * Supported USE types:
6412
+ * - USE BROWSER: Enables the agent to use a web browser tool
6413
+ * - USE SEARCH ENGINE (future): Enables search engine access
6414
+ * - USE FILE SYSTEM (future): Enables file system operations
6415
+ * - USE MCP (future): Enables MCP server connections
6416
+ *
6417
+ * The content following the USE commitment is ignored (similar to NOTE).
5450
6418
  *
5451
6419
  * Example usage in agent source:
5452
6420
  *
5453
6421
  * ```book
5454
- * RULE Always ask for clarification if the user's request is ambiguous
5455
- * RULES Never provide medical advice, always refer to healthcare professionals
6422
+ * USE BROWSER
6423
+ * USE SEARCH ENGINE
5456
6424
  * ```
5457
6425
  *
5458
6426
  * @private [๐Ÿช”] Maybe export the commitments through some package
5459
6427
  */
5460
- class RuleCommitmentDefinition extends BaseCommitmentDefinition {
5461
- constructor(type = 'RULE') {
5462
- super(type);
6428
+ class UseCommitmentDefinition extends BaseCommitmentDefinition {
6429
+ constructor() {
6430
+ super('USE');
5463
6431
  }
5464
6432
  /**
5465
- * Short one-line description of RULE/RULES.
6433
+ * Short one-line description of USE commitments.
5466
6434
  */
5467
6435
  get description() {
5468
- return 'Add behavioral rules the agent must follow.';
6436
+ return 'Enable the agent to use specific tools or capabilities (BROWSER, SEARCH ENGINE, etc.).';
5469
6437
  }
5470
6438
  /**
5471
6439
  * Icon for this commitment.
5472
6440
  */
5473
6441
  get icon() {
5474
- return 'โš–๏ธ';
6442
+ return '๐Ÿ”ง';
5475
6443
  }
5476
6444
  /**
5477
- * Markdown documentation for RULE/RULES commitment.
6445
+ * Markdown documentation for USE commitment.
5478
6446
  */
5479
6447
  get documentation() {
5480
6448
  return spaceTrim$1(`
5481
- # ${this.type}
6449
+ # USE
5482
6450
 
5483
- Adds behavioral constraints and guidelines that the agent must follow.
6451
+ Enables the agent to use specific tools or capabilities for interacting with external systems.
6452
+
6453
+ ## Supported USE types
6454
+
6455
+ - **USE BROWSER** - Enables the agent to use a web browser tool to access and retrieve information from the internet
6456
+ - **USE SEARCH ENGINE** (future) - Enables search engine access
6457
+ - **USE FILE SYSTEM** (future) - Enables file system operations
6458
+ - **USE MCP** (future) - Enables MCP server connections
5484
6459
 
5485
6460
  ## Key aspects
5486
6461
 
5487
- - All rules are treated equally regardless of singular/plural form.
5488
- - Rules define what the agent must or must not do.
6462
+ - The content following the USE commitment is ignored (similar to NOTE)
6463
+ - Multiple USE commitments can be specified to enable multiple capabilities
6464
+ - The actual tool usage is handled by the agent runtime
5489
6465
 
5490
6466
  ## Examples
5491
6467
 
6468
+ ### Basic browser usage
6469
+
5492
6470
  \`\`\`book
5493
- Customer Support Agent
6471
+ Research Assistant
5494
6472
 
5495
- PERSONA You are a helpful customer support representative
5496
- RULE Always ask for clarification if the user's request is ambiguous
5497
- RULE Be polite and professional in all interactions
5498
- RULES Never provide medical or legal advice
5499
- STYLE Maintain a friendly and helpful tone
6473
+ PERSONA You are a helpful research assistant
6474
+ USE BROWSER
6475
+ KNOWLEDGE Can search the web for up-to-date information
5500
6476
  \`\`\`
5501
6477
 
6478
+ ### Multiple tools
6479
+
5502
6480
  \`\`\`book
5503
- Educational Tutor
6481
+ Data Analyst
5504
6482
 
5505
- PERSONA You are a patient and knowledgeable tutor
5506
- RULE Break down complex concepts into simple steps
5507
- RULE Always encourage students and celebrate their progress
5508
- RULE If you don't know something, admit it and suggest resources
5509
- SAMPLE When explaining math: "Let's work through this step by step..."
6483
+ PERSONA You are a data analyst assistant
6484
+ USE BROWSER
6485
+ USE FILE SYSTEM
6486
+ ACTION Can analyze data from various sources
5510
6487
  \`\`\`
5511
6488
  `);
5512
6489
  }
5513
6490
  applyToAgentModelRequirements(requirements, content) {
6491
+ // USE commitments don't modify the system message or model requirements directly
6492
+ // They are handled separately in the parsing logic for capability extraction
6493
+ // This method exists for consistency with the CommitmentDefinition interface
6494
+ return requirements;
6495
+ }
6496
+ /**
6497
+ * Extracts the tool type from the USE commitment
6498
+ * This is used by the parsing logic
6499
+ */
6500
+ extractToolType(content) {
6501
+ var _a, _b;
5514
6502
  const trimmedContent = content.trim();
5515
- if (!trimmedContent) {
5516
- return requirements;
5517
- }
5518
- // Add rule to the system message
5519
- const ruleSection = `Rule: ${trimmedContent}`;
5520
- return this.appendToSystemMessage(requirements, ruleSection, '\n\n');
6503
+ // The tool type is the first word after USE (already stripped)
6504
+ const match = trimmedContent.match(/^(\w+)/);
6505
+ return (_b = (_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : null;
6506
+ }
6507
+ /**
6508
+ * Checks if this is a known USE type
6509
+ */
6510
+ isKnownUseType(useType) {
6511
+ const knownTypes = ['BROWSER', 'SEARCH ENGINE', 'FILE SYSTEM', 'MCP'];
6512
+ return knownTypes.includes(useType.toUpperCase());
5521
6513
  }
5522
6514
  }
5523
6515
  /**
@@ -5525,80 +6517,100 @@ class RuleCommitmentDefinition extends BaseCommitmentDefinition {
5525
6517
  */
5526
6518
 
5527
6519
  /**
5528
- * SAMPLE commitment definition
6520
+ * USE BROWSER commitment definition
5529
6521
  *
5530
- * The SAMPLE/EXAMPLE commitment provides examples of how the agent should respond
5531
- * or behave in certain situations. These examples help guide the agent's responses.
6522
+ * The `USE BROWSER` commitment indicates that the agent should utilize a web browser tool
6523
+ * to access and retrieve up-to-date information from the internet when necessary.
6524
+ *
6525
+ * The content following `USE BROWSER` is ignored (similar to NOTE).
5532
6526
  *
5533
6527
  * Example usage in agent source:
5534
6528
  *
5535
6529
  * ```book
5536
- * SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
5537
- * EXAMPLE For code questions, always include working code snippets
6530
+ * USE BROWSER
6531
+ * USE BROWSER This will be ignored
5538
6532
  * ```
5539
6533
  *
5540
6534
  * @private [๐Ÿช”] Maybe export the commitments through some package
5541
6535
  */
5542
- class SampleCommitmentDefinition extends BaseCommitmentDefinition {
5543
- constructor(type = 'SAMPLE') {
5544
- super(type);
6536
+ class UseBrowserCommitmentDefinition extends BaseCommitmentDefinition {
6537
+ constructor() {
6538
+ super('USE BROWSER', ['BROWSER']);
5545
6539
  }
5546
6540
  /**
5547
- * Short one-line description of SAMPLE/EXAMPLE.
6541
+ * Short one-line description of USE BROWSER.
5548
6542
  */
5549
6543
  get description() {
5550
- return 'Provide example responses to guide behavior.';
6544
+ return 'Enable the agent to use a web browser tool for accessing internet information.';
5551
6545
  }
5552
6546
  /**
5553
6547
  * Icon for this commitment.
5554
6548
  */
5555
6549
  get icon() {
5556
- return '๐Ÿ”';
6550
+ return '๐ŸŒ';
5557
6551
  }
5558
6552
  /**
5559
- * Markdown documentation for SAMPLE/EXAMPLE commitment.
6553
+ * Markdown documentation for USE BROWSER commitment.
5560
6554
  */
5561
6555
  get documentation() {
5562
6556
  return spaceTrim$1(`
5563
- # ${this.type}
6557
+ # USE BROWSER
5564
6558
 
5565
- Provides examples of how the agent should respond or behave in certain situations.
6559
+ Enables the agent to use a web browser tool to access and retrieve up-to-date information from the internet.
5566
6560
 
5567
6561
  ## Key aspects
5568
6562
 
5569
- - Both terms work identically and can be used interchangeably.
5570
- - Examples help guide the agent's response patterns and style.
6563
+ - The content following \`USE BROWSER\` is ignored (similar to NOTE)
6564
+ - The actual browser tool usage is handled by the agent runtime
6565
+ - Allows the agent to fetch current information from websites
6566
+ - Useful for research tasks, fact-checking, and accessing dynamic content
5571
6567
 
5572
6568
  ## Examples
5573
6569
 
5574
6570
  \`\`\`book
5575
- Sales Assistant
6571
+ Research Assistant
5576
6572
 
5577
- PERSONA You are a knowledgeable sales representative
5578
- SAMPLE When asked about pricing, respond: "Our basic plan starts at $10/month..."
5579
- SAMPLE For feature comparisons, create a clear comparison table
5580
- RULE Always be honest about limitations
6573
+ PERSONA You are a helpful research assistant specialized in finding current information
6574
+ USE BROWSER
6575
+ RULE Always cite your sources when providing information from the web
5581
6576
  \`\`\`
5582
6577
 
5583
6578
  \`\`\`book
5584
- Code Reviewer
6579
+ News Analyst
5585
6580
 
5586
- PERSONA You are an experienced software engineer
5587
- EXAMPLE For code questions, always include working code snippets
5588
- EXAMPLE When suggesting improvements: "Here's a more efficient approach..."
5589
- RULE Explain the reasoning behind your suggestions
5590
- STYLE Be constructive and encouraging in feedback
6581
+ PERSONA You are a news analyst who stays up-to-date with current events
6582
+ USE BROWSER
6583
+ STYLE Present news in a balanced and objective manner
6584
+ ACTION Can search for and summarize news articles
6585
+ \`\`\`
6586
+
6587
+ \`\`\`book
6588
+ Company Lawyer
6589
+
6590
+ PERSONA You are a company lawyer providing legal advice
6591
+ USE BROWSER
6592
+ KNOWLEDGE Corporate law and legal procedures
6593
+ RULE Always recommend consulting with a licensed attorney for specific legal matters
5591
6594
  \`\`\`
5592
6595
  `);
5593
6596
  }
5594
6597
  applyToAgentModelRequirements(requirements, content) {
5595
- const trimmedContent = content.trim();
5596
- if (!trimmedContent) {
5597
- return requirements;
5598
- }
5599
- // Add example to the system message
5600
- const exampleSection = `Example: ${trimmedContent}`;
5601
- return this.appendToSystemMessage(requirements, exampleSection, '\n\n');
6598
+ // We simply mark that browser capability is enabled in metadata
6599
+ // Get existing metadata
6600
+ const existingMetadata = requirements.metadata || {};
6601
+ // Get existing tools array or create new one
6602
+ const existingTools = existingMetadata.tools || [];
6603
+ // Add 'browser' to tools if not already present
6604
+ const updatedTools = existingTools.includes('browser') ? existingTools : [...existingTools, 'browser'];
6605
+ // Return requirements with updated metadata
6606
+ return {
6607
+ ...requirements,
6608
+ metadata: {
6609
+ ...existingMetadata,
6610
+ tools: updatedTools,
6611
+ useBrowser: true,
6612
+ },
6613
+ };
5602
6614
  }
5603
6615
  }
5604
6616
  /**
@@ -5606,123 +6618,76 @@ class SampleCommitmentDefinition extends BaseCommitmentDefinition {
5606
6618
  */
5607
6619
 
5608
6620
  /**
5609
- * SCENARIO commitment definition
6621
+ * USE MCP commitment definition
5610
6622
  *
5611
- * The SCENARIO commitment defines a specific situation or context in which the AI
5612
- * assistant should operate. It helps to set the scene for the AI's responses.
5613
- * Later scenarios are more important than earlier scenarios.
6623
+ * The `USE MCP` commitment allows to specify an MCP server URL which the agent will connect to
6624
+ * for retrieving additional instructions and actions.
6625
+ *
6626
+ * The content following `USE MCP` is the URL of the MCP server.
5614
6627
  *
5615
6628
  * Example usage in agent source:
5616
6629
  *
5617
6630
  * ```book
5618
- * SCENARIO You are in a customer service call center during peak hours
5619
- * SCENARIO The customer is frustrated and has been on hold for 20 minutes
5620
- * SCENARIO This is the customer's third call about the same issue
6631
+ * USE MCP http://mcp-server-url.com
5621
6632
  * ```
5622
6633
  *
5623
6634
  * @private [๐Ÿช”] Maybe export the commitments through some package
5624
6635
  */
5625
- class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
5626
- constructor(type = 'SCENARIO') {
5627
- super(type);
6636
+ class UseMcpCommitmentDefinition extends BaseCommitmentDefinition {
6637
+ constructor() {
6638
+ super('USE MCP', ['MCP']);
5628
6639
  }
5629
6640
  /**
5630
- * Short one-line description of SCENARIO.
6641
+ * Short one-line description of USE MCP.
5631
6642
  */
5632
6643
  get description() {
5633
- return 'Define specific **situations** or contexts for AI responses, with later scenarios having higher priority.';
6644
+ return 'Connects the agent to an external MCP server for additional capabilities.';
5634
6645
  }
5635
6646
  /**
5636
6647
  * Icon for this commitment.
5637
6648
  */
5638
6649
  get icon() {
5639
- return '๐ŸŽญ';
6650
+ return '๐Ÿ”Œ';
5640
6651
  }
5641
6652
  /**
5642
- * Markdown documentation for SCENARIO commitment.
6653
+ * Markdown documentation for USE MCP commitment.
5643
6654
  */
5644
6655
  get documentation() {
5645
6656
  return spaceTrim$1(`
5646
- # ${this.type}
6657
+ # USE MCP
5647
6658
 
5648
- Defines a specific situation or context in which the AI assistant should operate. It helps to set the scene for the AI's responses. Later scenarios are more important than earlier scenarios.
6659
+ Connects the agent to an external Model Context Protocol (MCP) server.
5649
6660
 
5650
6661
  ## Key aspects
5651
6662
 
5652
- - Multiple \`SCENARIO\` and \`SCENARIOS\` commitments build upon each other.
5653
- - Both terms work identically and can be used interchangeably.
5654
- - Later scenarios have higher priority and can override earlier scenarios.
5655
- - Provides situational context that influences response tone and content.
5656
- - Helps establish the environment and circumstances for interactions.
5657
-
5658
- ## Priority system
5659
-
5660
- When multiple scenarios are defined, they are processed in order, with later scenarios taking precedence over earlier ones when there are conflicts.
5661
-
5662
- ## Use cases
5663
-
5664
- - Setting the physical or virtual environment
5665
- - Establishing time constraints or urgency
5666
- - Defining relationship dynamics or power structures
5667
- - Creating emotional or situational context
5668
-
5669
- ## Examples
5670
-
5671
- \`\`\`book
5672
- Emergency Response Operator
5673
-
5674
- PERSONA You are an emergency response operator
5675
- SCENARIO You are handling a 911 emergency call
5676
- SCENARIO The caller is panicked and speaking rapidly
5677
- SCENARIO Time is critical - every second counts
5678
- GOAL Gather essential information quickly and dispatch appropriate help
5679
- RULE Stay calm and speak clearly
5680
- \`\`\`
5681
-
5682
- \`\`\`book
5683
- Sales Representative
5684
-
5685
- PERSONA You are a software sales representative
5686
- SCENARIO You are in the final meeting of a 6-month sales cycle
5687
- SCENARIO The client has budget approval and decision-making authority
5688
- SCENARIO Two competitors have also submitted proposals
5689
- SCENARIO The client values long-term partnership over lowest price
5690
- GOAL Close the deal while building trust for future business
5691
- \`\`\`
5692
-
5693
- \`\`\`book
5694
- Medical Assistant
6663
+ - The content following \`USE MCP\` must be a valid URL
6664
+ - Multiple MCP servers can be connected by using multiple \`USE MCP\` commitments
6665
+ - The agent will have access to tools and resources provided by the MCP server
5695
6666
 
5696
- PERSONA You are a medical assistant in a busy clinic
5697
- SCENARIO The waiting room is full and the doctor is running behind schedule
5698
- SCENARIO Patients are becoming impatient and anxious
5699
- SCENARIO You need to manage expectations while maintaining professionalism
5700
- SCENARIO Some patients have been waiting over an hour
5701
- GOAL Keep patients informed and calm while supporting efficient clinic flow
5702
- RULE Never provide medical advice or diagnosis
5703
- \`\`\`
6667
+ ## Example
5704
6668
 
5705
6669
  \`\`\`book
5706
- Technical Support Agent
6670
+ Company Lawyer
5707
6671
 
5708
- PERSONA You are a technical support agent
5709
- SCENARIO The customer is a small business owner during their busy season
5710
- SCENARIO Their main business system has been down for 2 hours
5711
- SCENARIO They are losing money every minute the system is offline
5712
- SCENARIO This is their first experience with your company
5713
- GOAL Resolve the issue quickly while creating a positive first impression
6672
+ PERSONA You are a company lawyer.
6673
+ USE MCP http://legal-db.example.com
5714
6674
  \`\`\`
5715
6675
  `);
5716
6676
  }
5717
6677
  applyToAgentModelRequirements(requirements, content) {
5718
- const trimmedContent = content.trim();
5719
- if (!trimmedContent) {
6678
+ const mcpServerUrl = content.trim();
6679
+ if (!mcpServerUrl) {
5720
6680
  return requirements;
5721
6681
  }
5722
- // Create scenario section for system message
5723
- const scenarioSection = `Scenario: ${trimmedContent}`;
5724
- // Scenarios provide important contextual information that affects behavior
5725
- return this.appendToSystemMessage(requirements, scenarioSection, '\n\n');
6682
+ const existingMcpServers = requirements.mcpServers || [];
6683
+ // Avoid duplicates
6684
+ if (existingMcpServers.includes(mcpServerUrl)) {
6685
+ return requirements;
6686
+ }
6687
+ return {
6688
+ ...requirements,
6689
+ mcpServers: [...existingMcpServers, mcpServerUrl],
6690
+ };
5726
6691
  }
5727
6692
  }
5728
6693
  /**
@@ -5730,85 +6695,94 @@ class ScenarioCommitmentDefinition extends BaseCommitmentDefinition {
5730
6695
  */
5731
6696
 
5732
6697
  /**
5733
- * STYLE commitment definition
6698
+ * USE SEARCH ENGINE commitment definition
5734
6699
  *
5735
- * The STYLE commitment defines how the agent should format and present its responses.
5736
- * This includes tone, writing style, formatting preferences, and communication patterns.
6700
+ * The `USE SEARCH ENGINE` commitment indicates that the agent should utilize a search engine tool
6701
+ * to access and retrieve up-to-date information from the internet when necessary.
6702
+ *
6703
+ * The content following `USE SEARCH ENGINE` is ignored (similar to NOTE).
5737
6704
  *
5738
6705
  * Example usage in agent source:
5739
6706
  *
5740
6707
  * ```book
5741
- * STYLE Write in a professional but friendly tone, use bullet points for lists
5742
- * STYLE Always provide code examples when explaining programming concepts
6708
+ * USE SEARCH ENGINE
6709
+ * USE SEARCH ENGINE This will be ignored
5743
6710
  * ```
5744
6711
  *
5745
6712
  * @private [๐Ÿช”] Maybe export the commitments through some package
5746
6713
  */
5747
- class StyleCommitmentDefinition extends BaseCommitmentDefinition {
5748
- constructor(type = 'STYLE') {
5749
- super(type);
6714
+ class UseSearchEngineCommitmentDefinition extends BaseCommitmentDefinition {
6715
+ constructor() {
6716
+ super('USE SEARCH ENGINE', ['SEARCH ENGINE', 'SEARCH']);
5750
6717
  }
5751
6718
  /**
5752
- * Short one-line description of STYLE.
6719
+ * Short one-line description of USE SEARCH ENGINE.
5753
6720
  */
5754
6721
  get description() {
5755
- return 'Control the tone and writing style of responses.';
6722
+ return 'Enable the agent to use a search engine tool for accessing internet information.';
5756
6723
  }
5757
6724
  /**
5758
6725
  * Icon for this commitment.
5759
6726
  */
5760
6727
  get icon() {
5761
- return '๐Ÿ–‹๏ธ';
6728
+ return '๐Ÿ”';
5762
6729
  }
5763
6730
  /**
5764
- * Markdown documentation for STYLE commitment.
6731
+ * Markdown documentation for USE SEARCH ENGINE commitment.
5765
6732
  */
5766
6733
  get documentation() {
5767
6734
  return spaceTrim$1(`
5768
- # ${this.type}
6735
+ # USE SEARCH ENGINE
5769
6736
 
5770
- Defines how the agent should format and present its responses (tone, writing style, formatting).
6737
+ Enables the agent to use a search engine tool to access and retrieve up-to-date information from the internet.
5771
6738
 
5772
6739
  ## Key aspects
5773
6740
 
5774
- - Both terms work identically and can be used interchangeably.
5775
- - Later style instructions can override earlier ones.
5776
- - Style affects both tone and presentation format.
6741
+ - The content following \`USE SEARCH ENGINE\` is ignored (similar to NOTE)
6742
+ - The actual search engine tool usage is handled by the agent runtime
6743
+ - Allows the agent to search for current information from the web
6744
+ - Useful for research tasks, finding facts, and accessing dynamic content
5777
6745
 
5778
6746
  ## Examples
5779
6747
 
5780
6748
  \`\`\`book
5781
- Technical Writer
6749
+ Research Assistant
5782
6750
 
5783
- PERSONA You are a technical documentation expert
5784
- STYLE Write in a professional but friendly tone, use bullet points for lists
5785
- STYLE Always provide code examples when explaining programming concepts
5786
- FORMAT Use markdown formatting with clear headings
6751
+ PERSONA You are a helpful research assistant specialized in finding current information
6752
+ USE SEARCH ENGINE
6753
+ RULE Always cite your sources when providing information from the web
5787
6754
  \`\`\`
5788
6755
 
5789
6756
  \`\`\`book
5790
- Creative Assistant
6757
+ Fact Checker
5791
6758
 
5792
- PERSONA You are a creative writing helper
5793
- STYLE Be enthusiastic and encouraging in your responses
5794
- STYLE Use vivid metaphors and analogies to explain concepts
5795
- STYLE Keep responses conversational and engaging
5796
- RULE Always maintain a positive and supportive tone
6759
+ PERSONA You are a fact checker
6760
+ USE SEARCH ENGINE
6761
+ ACTION Search for claims and verify them against reliable sources
5797
6762
  \`\`\`
5798
6763
  `);
5799
6764
  }
5800
6765
  applyToAgentModelRequirements(requirements, content) {
5801
- const trimmedContent = content.trim();
5802
- if (!trimmedContent) {
5803
- return requirements;
5804
- }
5805
- // Add style instructions to the system message
5806
- const styleSection = `Style: ${trimmedContent}`;
5807
- return this.appendToSystemMessage(requirements, styleSection, '\n\n');
6766
+ // We simply mark that search engine capability is enabled in metadata
6767
+ // Get existing metadata
6768
+ const existingMetadata = requirements.metadata || {};
6769
+ // Get existing tools array or create new one
6770
+ const existingTools = existingMetadata.tools || [];
6771
+ // Add 'search-engine' to tools if not already present
6772
+ const updatedTools = existingTools.includes('search-engine') ? existingTools : [...existingTools, 'search-engine'];
6773
+ // Return requirements with updated metadata
6774
+ return {
6775
+ ...requirements,
6776
+ metadata: {
6777
+ ...existingMetadata,
6778
+ tools: updatedTools,
6779
+ useSearchEngine: true,
6780
+ },
6781
+ };
5808
6782
  }
5809
6783
  }
5810
6784
  /**
5811
- * [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
6785
+ * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5812
6786
  */
5813
6787
 
5814
6788
  /**
@@ -5897,16 +6871,22 @@ const COMMITMENT_REGISTRY = [
5897
6871
  new StyleCommitmentDefinition('STYLES'),
5898
6872
  new RuleCommitmentDefinition('RULE'),
5899
6873
  new RuleCommitmentDefinition('RULES'),
6874
+ new LanguageCommitmentDefinition('LANGUAGE'),
6875
+ new LanguageCommitmentDefinition('LANGUAGES'),
5900
6876
  new SampleCommitmentDefinition('SAMPLE'),
5901
6877
  new SampleCommitmentDefinition('EXAMPLE'),
5902
6878
  new FormatCommitmentDefinition('FORMAT'),
5903
6879
  new FormatCommitmentDefinition('FORMATS'),
6880
+ new FromCommitmentDefinition('FROM'),
5904
6881
  new ModelCommitmentDefinition('MODEL'),
5905
6882
  new ModelCommitmentDefinition('MODELS'),
5906
6883
  new ActionCommitmentDefinition('ACTION'),
5907
6884
  new ActionCommitmentDefinition('ACTIONS'),
6885
+ new ComponentCommitmentDefinition(),
5908
6886
  new MetaImageCommitmentDefinition(),
5909
6887
  new MetaColorCommitmentDefinition(),
6888
+ new MetaFontCommitmentDefinition(),
6889
+ new MetaLinkCommitmentDefinition(),
5910
6890
  new MetaCommitmentDefinition(),
5911
6891
  new NoteCommitmentDefinition('NOTE'),
5912
6892
  new NoteCommitmentDefinition('NOTES'),
@@ -5925,6 +6905,12 @@ const COMMITMENT_REGISTRY = [
5925
6905
  new DeleteCommitmentDefinition('CANCEL'),
5926
6906
  new DeleteCommitmentDefinition('DISCARD'),
5927
6907
  new DeleteCommitmentDefinition('REMOVE'),
6908
+ new OpenCommitmentDefinition(),
6909
+ new ClosedCommitmentDefinition(),
6910
+ new UseBrowserCommitmentDefinition(),
6911
+ new UseSearchEngineCommitmentDefinition(),
6912
+ new UseMcpCommitmentDefinition(),
6913
+ new UseCommitmentDefinition(),
5928
6914
  // Not yet implemented commitments (using placeholder)
5929
6915
  new NotYetImplementedCommitmentDefinition('EXPECT'),
5930
6916
  new NotYetImplementedCommitmentDefinition('BEHAVIOUR'),
@@ -5957,6 +6943,11 @@ function getAllCommitmentDefinitions() {
5957
6943
  * Note: [๐Ÿ’ž] Ignore a discrepancy between file name and entity name
5958
6944
  */
5959
6945
 
6946
+ /**
6947
+ * Regex pattern to match horizontal lines (markdown thematic breaks)
6948
+ * Matches 3 or more hyphens, underscores, or asterisks (with optional spaces between)
6949
+ */
6950
+ const HORIZONTAL_LINE_PATTERN = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
5960
6951
  /**
5961
6952
  * Parses agent source using the new commitment system with multiline support
5962
6953
  * This function replaces the hardcoded commitment parsing in the original parseAgentSource
@@ -6019,6 +7010,24 @@ function parseAgentSourceWithCommitments(agentSource) {
6019
7010
  break;
6020
7011
  }
6021
7012
  }
7013
+ // Check if this is a horizontal line (ends any current commitment)
7014
+ const isHorizontalLine = HORIZONTAL_LINE_PATTERN.test(line);
7015
+ if (isHorizontalLine) {
7016
+ // Save the current commitment if it exists
7017
+ if (currentCommitment) {
7018
+ const fullContent = currentCommitment.contentLines.join('\n');
7019
+ commitments.push({
7020
+ type: currentCommitment.type,
7021
+ content: spaceTrim$1(fullContent),
7022
+ originalLine: currentCommitment.originalStartLine,
7023
+ lineNumber: currentCommitment.startLineNumber,
7024
+ });
7025
+ currentCommitment = null;
7026
+ }
7027
+ // Add horizontal line to non-commitment lines
7028
+ nonCommitmentLines.push(line);
7029
+ continue;
7030
+ }
6022
7031
  if (!foundNewCommitment) {
6023
7032
  if (currentCommitment) {
6024
7033
  // This line belongs to the current commitment
@@ -6105,16 +7114,6 @@ function parseParameters(text) {
6105
7114
  return uniqueParameters;
6106
7115
  }
6107
7116
 
6108
- /**
6109
- * Creates temporary default agent name based on agent source hash
6110
- *
6111
- * @public exported from `@promptbook/core`
6112
- */
6113
- function createDefaultAgentName(agentSource) {
6114
- const agentHash = computeAgentHash(agentSource);
6115
- return normalizeAgentName(`Agent ${agentHash.substring(0, 6)}`);
6116
- }
6117
-
6118
7117
  /**
6119
7118
  * Parses basic information from agent source
6120
7119
  *
@@ -6154,15 +7153,21 @@ function parseAgentSource(agentSource) {
6154
7153
  const links = [];
6155
7154
  for (const commitment of parseResult.commitments) {
6156
7155
  if (commitment.type === 'META LINK') {
6157
- links.push(spaceTrim(commitment.content));
7156
+ const linkValue = spaceTrim$2(commitment.content);
7157
+ links.push(linkValue);
7158
+ meta.link = linkValue;
6158
7159
  continue;
6159
7160
  }
6160
7161
  if (commitment.type === 'META IMAGE') {
6161
- meta.image = spaceTrim(commitment.content);
7162
+ meta.image = spaceTrim$2(commitment.content);
6162
7163
  continue;
6163
7164
  }
6164
7165
  if (commitment.type === 'META COLOR') {
6165
- meta.color = spaceTrim(commitment.content);
7166
+ meta.color = spaceTrim$2(commitment.content);
7167
+ continue;
7168
+ }
7169
+ if (commitment.type === 'META FONT') {
7170
+ meta.font = spaceTrim$2(commitment.content);
6166
7171
  continue;
6167
7172
  }
6168
7173
  if (commitment.type !== 'META') {
@@ -6171,10 +7176,10 @@ function parseAgentSource(agentSource) {
6171
7176
  // Parse META commitments - format is "META TYPE content"
6172
7177
  const metaTypeRaw = commitment.content.split(' ')[0] || 'NONE';
6173
7178
  if (metaTypeRaw === 'LINK') {
6174
- links.push(spaceTrim(commitment.content.substring(metaTypeRaw.length)));
7179
+ links.push(spaceTrim$2(commitment.content.substring(metaTypeRaw.length)));
6175
7180
  }
6176
7181
  const metaType = normalizeTo_camelCase(metaTypeRaw);
6177
- meta[metaType] = spaceTrim(commitment.content.substring(metaTypeRaw.length));
7182
+ meta[metaType] = spaceTrim$2(commitment.content.substring(metaTypeRaw.length));
6178
7183
  }
6179
7184
  // Generate gravatar fallback if no meta image specified
6180
7185
  if (!meta.image) {
@@ -6312,7 +7317,7 @@ function validateBook(source) {
6312
7317
  * @deprecated Use `$generateBookBoilerplate` instead
6313
7318
  * @public exported from `@promptbook/core`
6314
7319
  */
6315
- const DEFAULT_BOOK = padBook(validateBook(spaceTrim(`
7320
+ const DEFAULT_BOOK = padBook(validateBook(spaceTrim$2(`
6316
7321
  AI Avatar
6317
7322
 
6318
7323
  PERSONA A friendly AI assistant that helps you with your tasks
@@ -6661,7 +7666,7 @@ function MarkdownContent(props) {
6661
7666
  function aboutPromptbookInformation(options) {
6662
7667
  const { isServersInfoIncluded = true, isRuntimeEnvironmentInfoIncluded = true } = options || {};
6663
7668
  const fullInfoPieces = [];
6664
- const basicInfo = spaceTrim(`
7669
+ const basicInfo = spaceTrim$2(`
6665
7670
 
6666
7671
  # ${NAME}
6667
7672
 
@@ -6673,7 +7678,7 @@ function aboutPromptbookInformation(options) {
6673
7678
  `);
6674
7679
  fullInfoPieces.push(basicInfo);
6675
7680
  if (isServersInfoIncluded) {
6676
- const serversInfo = spaceTrim((block) => `
7681
+ const serversInfo = spaceTrim$2((block) => `
6677
7682
 
6678
7683
  ## Servers
6679
7684
 
@@ -6688,7 +7693,7 @@ function aboutPromptbookInformation(options) {
6688
7693
  ...runtimeEnvironment,
6689
7694
  isCostPrevented: IS_COST_PREVENTED,
6690
7695
  };
6691
- const environmentInfo = spaceTrim((block) => `
7696
+ const environmentInfo = spaceTrim$2((block) => `
6692
7697
 
6693
7698
  ## Environment
6694
7699
 
@@ -6698,7 +7703,7 @@ function aboutPromptbookInformation(options) {
6698
7703
  `);
6699
7704
  fullInfoPieces.push(environmentInfo);
6700
7705
  }
6701
- const fullInfo = spaceTrim(fullInfoPieces.join('\n\n'));
7706
+ const fullInfo = spaceTrim$2(fullInfoPieces.join('\n\n'));
6702
7707
  return fullInfo;
6703
7708
  }
6704
7709
  /**
@@ -7820,7 +8825,7 @@ function getTextColor(bgColor) {
7820
8825
  const htmlSaveFormatDefinition = {
7821
8826
  formatName: 'html',
7822
8827
  label: 'Html',
7823
- getContent: ({ messages }) => spaceTrim(`
8828
+ getContent: ({ messages }) => spaceTrim$2(`
7824
8829
  <!DOCTYPE html>
7825
8830
  <html lang="en">
7826
8831
  <head>
@@ -7908,7 +8913,7 @@ const htmlSaveFormatDefinition = {
7908
8913
  };
7909
8914
  const bgColor = participantColors[String(message.from)] || '#2b7cff';
7910
8915
  const textColor = getTextColor(bgColor);
7911
- return spaceTrim(`
8916
+ return spaceTrim$2(`
7912
8917
  <div class="chat-message">
7913
8918
  <div class="avatar" style="background:${bgColor};color:${getTextColor(bgColor)};">
7914
8919
  ${String(message.from)[0] || '?'}
@@ -8011,7 +9016,7 @@ const reactSaveFormatDefinition = {
8011
9016
  const { imports: participantsImports, value: participantsValue } = serializeToPromptbookJavascript(participants);
8012
9017
  const { imports: messagesImports, value: messagesValue } = serializeToPromptbookJavascript(messages);
8013
9018
  const uniqueImports = Array.from(new Set([`import { Chat } from '@promptbook/components';`, ...participantsImports, ...messagesImports])).filter((imp) => !!imp && imp.trim().length > 0);
8014
- return spaceTrim((block) => `
9019
+ return spaceTrim$2((block) => `
8015
9020
  "use client";
8016
9021
 
8017
9022
  ${block(uniqueImports.join('\n'))}
@@ -8220,7 +9225,7 @@ const ChatMessageItem = memo(({ message, participant, participants, isLastMessag
8220
9225
  // Note: Do not hide tooltip on mouse leave, it will be hidden by clicking outside
8221
9226
  };
8222
9227
  const isMe = participant === null || participant === void 0 ? void 0 : participant.isMe;
8223
- const color = Color.from((participant && participant.color) || (isMe ? USER_CHAT_COLOR : PROMPTBOOK_CHAT_COLOR));
9228
+ const color = Color.fromSafe((participant && participant.color) || (isMe ? USER_CHAT_COLOR : PROMPTBOOK_CHAT_COLOR));
8224
9229
  const colorOfText = color.then(textColor);
8225
9230
  const { contentWithoutButtons, buttons } = parseMessageButtons(message.content);
8226
9231
  const shouldShowButtons = isLastMessage && buttons.length > 0 && onMessage;
@@ -8501,7 +9506,7 @@ function Chat(props) {
8501
9506
  const fileContents = uploadedFiles.map((f) => f.content).join(' ');
8502
9507
  messageContent = messageContent ? `${messageContent} ${fileContents}` : fileContents;
8503
9508
  }
8504
- if (spaceTrim(messageContent) === '') {
9509
+ if (spaceTrim$2(messageContent) === '') {
8505
9510
  throw new Error(`You need to write some text or upload a file`);
8506
9511
  }
8507
9512
  await onMessage(messageContent);
@@ -8857,7 +9862,7 @@ ChatPersistence.STORAGE_PREFIX = 'promptbook_chat_';
8857
9862
  * @public exported from `@promptbook/components`
8858
9863
  */
8859
9864
  function LlmChat(props) {
8860
- const { llmTools, persistenceKey, onChange, onReset, initialMessages, sendMessage, userParticipantName = 'USER', llmParticipantName = 'ASSISTANT', ...restProps } = props;
9865
+ const { llmTools, persistenceKey, onChange, onReset, initialMessages, sendMessage, userParticipantName = 'USER', llmParticipantName = 'ASSISTANT', autoExecuteMessage, ...restProps } = props;
8861
9866
  // Internal state management
8862
9867
  // DRY: Single factory for seeding initial messages (used on mount and after reset)
8863
9868
  const buildInitialMessages = useCallback(() => (initialMessages ? [...initialMessages] : []), [initialMessages]);
@@ -9191,6 +10196,14 @@ function LlmChat(props) {
9191
10196
  sendMessage._attach(handleMessage);
9192
10197
  }
9193
10198
  }, [sendMessage, handleMessage]);
10199
+ // Handle autoExecuteMessage
10200
+ const hasAutoExecutedRef = useRef(false);
10201
+ useEffect(() => {
10202
+ if (autoExecuteMessage && !hasAutoExecutedRef.current) {
10203
+ hasAutoExecutedRef.current = true;
10204
+ handleMessage(autoExecuteMessage);
10205
+ }
10206
+ }, [autoExecuteMessage, handleMessage]);
9194
10207
  return (jsx(Chat, { ...restProps, messages, onReset, tasksProgress, participants, onMessage: handleMessage, onReset: handleReset, onVoiceInput: llmTools.callVoiceChatModel ? handleVoiceInput : undefined, isVoiceCalling: isVoiceCalling }));
9195
10208
  }
9196
10209
 
@@ -9213,7 +10226,7 @@ function AgentChat(props) {
9213
10226
  {
9214
10227
  from: 'AGENT',
9215
10228
  content: agent.initialMessage ||
9216
- spaceTrim(`
10229
+ spaceTrim$2(`
9217
10230
 
9218
10231
  Hello! I am ${agent.meta.fullname || agent.agentName || 'an AI Agent'}.
9219
10232
 
@@ -9681,7 +10694,7 @@ function book(strings, ...values) {
9681
10694
  const bookString = prompt(strings, ...values);
9682
10695
  if (!isValidPipelineString(bookString)) {
9683
10696
  // TODO: Make the CustomError for this
9684
- throw new Error(spaceTrim(`
10697
+ throw new Error(spaceTrim$2(`
9685
10698
  The string is not a valid pipeline string
9686
10699
 
9687
10700
  book\`
@@ -9691,7 +10704,7 @@ function book(strings, ...values) {
9691
10704
  }
9692
10705
  if (!isValidBook(bookString)) {
9693
10706
  // TODO: Make the CustomError for this
9694
- throw new Error(spaceTrim(`
10707
+ throw new Error(spaceTrim$2(`
9695
10708
  The string is not a valid book
9696
10709
 
9697
10710
  book\`
@@ -9754,14 +10767,14 @@ class MultipleLlmExecutionTools {
9754
10767
  if (description === undefined) {
9755
10768
  return headLine;
9756
10769
  }
9757
- return spaceTrim((block) => `
10770
+ return spaceTrim$2((block) => `
9758
10771
  ${headLine}
9759
10772
 
9760
10773
  ${ /* <- Note: Indenting the description: */block(description)}
9761
10774
  `);
9762
10775
  })
9763
10776
  .join('\n\n');
9764
- return spaceTrim((block) => `
10777
+ return spaceTrim$2((block) => `
9765
10778
  Multiple LLM Providers:
9766
10779
 
9767
10780
  ${block(innerModelsTitlesAndDescriptions)}
@@ -9852,7 +10865,7 @@ class MultipleLlmExecutionTools {
9852
10865
  // 1) OpenAI throw PipelineExecutionError: Parameter `{knowledge}` is not defined
9853
10866
  // 2) AnthropicClaude throw PipelineExecutionError: Parameter `{knowledge}` is not defined
9854
10867
  // 3) ...
9855
- spaceTrim((block) => `
10868
+ spaceTrim$2((block) => `
9856
10869
  All execution tools of ${this.title} failed:
9857
10870
 
9858
10871
  ${block(errors
@@ -9865,7 +10878,7 @@ class MultipleLlmExecutionTools {
9865
10878
  throw new PipelineExecutionError(`You have not provided any \`LlmExecutionTools\` into ${this.title}`);
9866
10879
  }
9867
10880
  else {
9868
- throw new PipelineExecutionError(spaceTrim((block) => `
10881
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
9869
10882
  You have not provided any \`LlmExecutionTools\` that support model variant "${prompt.modelRequirements.modelVariant}" into ${this.title}
9870
10883
 
9871
10884
  Available \`LlmExecutionTools\`:
@@ -9898,7 +10911,7 @@ class MultipleLlmExecutionTools {
9898
10911
  */
9899
10912
  function joinLlmExecutionTools(title, ...llmExecutionTools) {
9900
10913
  if (llmExecutionTools.length === 0) {
9901
- const warningMessage = spaceTrim(`
10914
+ const warningMessage = spaceTrim$2(`
9902
10915
  You have not provided any \`LlmExecutionTools\`
9903
10916
  This means that you won't be able to execute any prompts that require large language models like GPT-4 or Anthropic's Claude.
9904
10917
 
@@ -10077,7 +11090,7 @@ function pipelineJsonToString(pipelineJson) {
10077
11090
  pipelineString += '\n\n';
10078
11091
  pipelineString += '```' + contentLanguage;
10079
11092
  pipelineString += '\n';
10080
- pipelineString += spaceTrim(content);
11093
+ pipelineString += spaceTrim$2(content);
10081
11094
  // <- TODO: [main] !!3 Escape
10082
11095
  // <- TODO: [๐Ÿง ] Some clear strategy how to spaceTrim the blocks
10083
11096
  pipelineString += '\n';
@@ -11138,14 +12151,14 @@ function $registeredScrapersMessage(availableScrapers) {
11138
12151
  return { ...metadata, isMetadataAviailable, isInstalled, isAvailableInTools };
11139
12152
  });
11140
12153
  if (metadata.length === 0) {
11141
- return spaceTrim(`
12154
+ return spaceTrim$2(`
11142
12155
  **No scrapers are available**
11143
12156
 
11144
12157
  This is a unexpected behavior, you are probably using some broken version of Promptbook
11145
12158
  At least there should be available the metadata of the scrapers
11146
12159
  `);
11147
12160
  }
11148
- return spaceTrim((block) => `
12161
+ return spaceTrim$2((block) => `
11149
12162
  Available scrapers are:
11150
12163
  ${block(metadata
11151
12164
  .map(({ packageName, className, isMetadataAviailable, isInstalled, mimeTypes, isAvailableInBrowser, isAvailableInTools, }, i) => {
@@ -11291,7 +12304,7 @@ const promptbookFetch = async (urlOrRequest, init) => {
11291
12304
  else if (urlOrRequest instanceof Request) {
11292
12305
  url = urlOrRequest.url;
11293
12306
  }
11294
- throw new PromptbookFetchError(spaceTrim((block) => `
12307
+ throw new PromptbookFetchError(spaceTrim$2((block) => `
11295
12308
  Can not fetch "${url}"
11296
12309
 
11297
12310
  Fetch error:
@@ -11452,7 +12465,7 @@ async function makeKnowledgeSourceHandler(knowledgeSource, tools, options) {
11452
12465
  const fileExtension = getFileExtension(filename);
11453
12466
  const mimeType = extensionToMimeType(fileExtension || '');
11454
12467
  if (!(await isFileExisting(filename, tools.fs))) {
11455
- throw new NotFoundError(spaceTrim((block) => `
12468
+ throw new NotFoundError(spaceTrim$2((block) => `
11456
12469
  Can not make source handler for file which does not exist:
11457
12470
 
11458
12471
  File:
@@ -11545,7 +12558,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
11545
12558
  // <- TODO: [๐Ÿช“] Here should be no need for spreading new array, just `partialPieces = partialPiecesUnchecked`
11546
12559
  break;
11547
12560
  }
11548
- console.warn(spaceTrim((block) => `
12561
+ console.warn(spaceTrim$2((block) => `
11549
12562
  Cannot scrape knowledge from source despite the scraper \`${scraper.metadata.className}\` supports the mime type "${sourceHandler.mimeType}".
11550
12563
 
11551
12564
  The source:
@@ -11561,7 +12574,7 @@ async function prepareKnowledgePieces(knowledgeSources, tools, options) {
11561
12574
  // <- TODO: [๐Ÿฎ] Some standard way how to transform errors into warnings and how to handle non-critical fails during the tasks
11562
12575
  }
11563
12576
  if (partialPieces === null) {
11564
- throw new KnowledgeScrapeError(spaceTrim((block) => `
12577
+ throw new KnowledgeScrapeError(spaceTrim$2((block) => `
11565
12578
  Cannot scrape knowledge
11566
12579
 
11567
12580
  The source:
@@ -11998,7 +13011,7 @@ const CsvFormatParser = {
11998
13011
  const { value, outputParameterName, settings, mapCallback, onProgress } = options;
11999
13012
  const csv = csvParse(value, settings);
12000
13013
  if (csv.errors.length !== 0) {
12001
- throw new CsvFormatError(spaceTrim((block) => `
13014
+ throw new CsvFormatError(spaceTrim$2((block) => `
12002
13015
  CSV parsing error
12003
13016
 
12004
13017
  Error(s) from CSV parsing:
@@ -12043,7 +13056,7 @@ const CsvFormatParser = {
12043
13056
  const { value, settings, mapCallback, onProgress } = options;
12044
13057
  const csv = csvParse(value, settings);
12045
13058
  if (csv.errors.length !== 0) {
12046
- throw new CsvFormatError(spaceTrim((block) => `
13059
+ throw new CsvFormatError(spaceTrim$2((block) => `
12047
13060
  CSV parsing error
12048
13061
 
12049
13062
  Error(s) from CSV parsing:
@@ -12229,7 +13242,7 @@ function mapAvailableToExpectedParameters(options) {
12229
13242
  }
12230
13243
  // Phase 2๏ธโƒฃ: Non-matching mapping
12231
13244
  if (expectedParameterNames.size !== availableParametersNames.size) {
12232
- throw new PipelineExecutionError(spaceTrim((block) => `
13245
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
12233
13246
  Can not map available parameters to expected parameters
12234
13247
 
12235
13248
  Mapped parameters:
@@ -12801,7 +13814,7 @@ async function executeFormatSubvalues(options) {
12801
13814
  return /* not await */ executeAttempts({ ...options, logLlmCall });
12802
13815
  }
12803
13816
  if (jokerParameterNames.length !== 0) {
12804
- throw new UnexpectedError(spaceTrim((block) => `
13817
+ throw new UnexpectedError(spaceTrim$2((block) => `
12805
13818
  JOKER parameters are not supported together with FOREACH command
12806
13819
 
12807
13820
  [๐Ÿงžโ€โ™€๏ธ] This should be prevented in \`validatePipeline\`
@@ -12814,7 +13827,7 @@ async function executeFormatSubvalues(options) {
12814
13827
  if (formatDefinition === undefined) {
12815
13828
  throw new UnexpectedError(
12816
13829
  // <- TODO: [๐Ÿง ][๐Ÿง] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
12817
- spaceTrim((block) => `
13830
+ spaceTrim$2((block) => `
12818
13831
  Unsupported format "${task.foreach.formatName}"
12819
13832
 
12820
13833
  Available formats:
@@ -12831,7 +13844,7 @@ async function executeFormatSubvalues(options) {
12831
13844
  if (subvalueParser === undefined) {
12832
13845
  throw new UnexpectedError(
12833
13846
  // <- TODO: [๐Ÿง ][๐Ÿง] Should be formats fixed per promptbook version or behave as plugins (=> change UnexpectedError)
12834
- spaceTrim((block) => `
13847
+ spaceTrim$2((block) => `
12835
13848
  Unsupported subformat name "${task.foreach.subformatName}" for format "${task.foreach.formatName}"
12836
13849
 
12837
13850
  Available subformat names for format "${formatDefinition.formatName}":
@@ -12871,7 +13884,7 @@ async function executeFormatSubvalues(options) {
12871
13884
  if (!(error instanceof PipelineExecutionError)) {
12872
13885
  throw error;
12873
13886
  }
12874
- const highLevelError = new PipelineExecutionError(spaceTrim((block) => `
13887
+ const highLevelError = new PipelineExecutionError(spaceTrim$2((block) => `
12875
13888
  ${error.message}
12876
13889
 
12877
13890
  This is error in FOREACH command when mapping ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
@@ -12895,7 +13908,7 @@ async function executeFormatSubvalues(options) {
12895
13908
  ...options,
12896
13909
  priority: priority + index,
12897
13910
  parameters: allSubparameters,
12898
- pipelineIdentification: spaceTrim((block) => `
13911
+ pipelineIdentification: spaceTrim$2((block) => `
12899
13912
  ${block(pipelineIdentification)}
12900
13913
  Subparameter index: ${index}
12901
13914
  `),
@@ -12904,7 +13917,7 @@ async function executeFormatSubvalues(options) {
12904
13917
  }
12905
13918
  catch (error) {
12906
13919
  if (length > BIG_DATASET_TRESHOLD) {
12907
- console.error(spaceTrim((block) => `
13920
+ console.error(spaceTrim$2((block) => `
12908
13921
  ${error.message}
12909
13922
 
12910
13923
  This is error in FOREACH command when processing ${formatDefinition.formatName} ${subvalueParser.subvalueName} data (${index + 1}/${length})
@@ -15262,7 +16275,7 @@ class OpenAiCompatibleExecutionTools {
15262
16275
  // Note: Match exact or prefix for model families
15263
16276
  const model = this.HARDCODED_MODELS.find(({ modelName }) => modelName === defaultModelName || modelName.startsWith(defaultModelName));
15264
16277
  if (model === undefined) {
15265
- throw new PipelineExecutionError(spaceTrim((block) => `
16278
+ throw new PipelineExecutionError(spaceTrim$2((block) => `
15266
16279
  Cannot find model in ${this.title} models with name "${defaultModelName}" which should be used as default.
15267
16280
 
15268
16281
  Available models:
@@ -15517,18 +16530,26 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
15517
16530
  modelName: 'assistant',
15518
16531
  // <- [๐Ÿง ] What is the best value here
15519
16532
  });
16533
+ // Build thread messages: include previous thread messages + current user message
16534
+ const threadMessages = [];
16535
+ // TODO: [๐Ÿˆน] Maybe this should not be here but in other place, look at commit 39d705e75e5bcf7a818c3af36bc13e1c8475c30c
16536
+ // Add previous messages from thread (if any)
16537
+ if ('thread' in prompt &&
16538
+ Array.isArray(prompt.thread)) {
16539
+ const previousMessages = prompt.thread.map((msg) => ({
16540
+ role: (msg.role === 'assistant' ? 'assistant' : 'user'),
16541
+ content: msg.content,
16542
+ }));
16543
+ threadMessages.push(...previousMessages);
16544
+ }
16545
+ // Always add the current user message
16546
+ threadMessages.push({ role: 'user', content: rawPromptContent });
15520
16547
  const rawRequest = {
15521
16548
  // TODO: [๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง] ...modelSettings,
15522
16549
  // TODO: [๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง][๐Ÿง ] What about system message for assistants, does it make sense - combination of OpenAI assistants with Promptbook Personas
15523
16550
  assistant_id: this.assistantId,
15524
16551
  thread: {
15525
- messages: 'thread' in prompt &&
15526
- Array.isArray(prompt.thread)
15527
- ? prompt.thread.map((msg) => ({
15528
- role: msg.role === 'assistant' ? 'assistant' : 'user',
15529
- content: msg.content,
15530
- }))
15531
- : [{ role: 'user', content: rawPromptContent }],
16552
+ messages: threadMessages,
15532
16553
  },
15533
16554
  // <- TODO: Add user identification here> user: this.options.user,
15534
16555
  };
@@ -15548,7 +16569,7 @@ class OpenAiAssistantExecutionTools extends OpenAiExecutionTools {
15548
16569
  console.info('textDelta', textDelta.value);
15549
16570
  }
15550
16571
  const chunk = {
15551
- content: textDelta.value || '',
16572
+ content: snapshot.value,
15552
16573
  modelName: 'assistant',
15553
16574
  timing: {
15554
16575
  start,
@@ -16169,6 +17190,7 @@ class Agent extends AgentLlmExecutionTools {
16169
17190
  * Note: This method also implements the learning mechanism
16170
17191
  */
16171
17192
  async callChatModelStream(prompt, onProgress) {
17193
+ var _a;
16172
17194
  // [1] Check if the user is asking the same thing as in the samples
16173
17195
  const modelRequirements = await this.getAgentModelRequirements();
16174
17196
  if (modelRequirements.samples) {
@@ -16216,9 +17238,12 @@ class Agent extends AgentLlmExecutionTools {
16216
17238
  if (result.rawResponse && 'sample' in result.rawResponse) {
16217
17239
  return result;
16218
17240
  }
17241
+ if ((_a = modelRequirements.metadata) === null || _a === void 0 ? void 0 : _a.isClosed) {
17242
+ return result;
17243
+ }
16219
17244
  // TODO: !!! Extract learning to separate method
16220
17245
  // Learning: Append the conversation sample to the agent source
16221
- const learningExample = spaceTrim((block) => `
17246
+ const learningExample = spaceTrim$2((block) => `
16222
17247
 
16223
17248
  ---
16224
17249
 
@@ -16231,7 +17256,7 @@ class Agent extends AgentLlmExecutionTools {
16231
17256
  `);
16232
17257
  // Append to the current source
16233
17258
  const currentSource = this.agentSource.value;
16234
- const newSource = padBook(validateBook(spaceTrim(currentSource) + '\n\n' + learningExample));
17259
+ const newSource = padBook(validateBook(spaceTrim$2(currentSource) + '\n\n' + learningExample));
16235
17260
  // Update the source (which will trigger the subscription and update the underlying tools)
16236
17261
  this.agentSource.next(newSource);
16237
17262
  return result;