@promptbook/components 0.104.0-1 → 0.104.0-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/esm/index.es.js +488 -185
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/types.index.d.ts +8 -2
  4. package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +6 -1
  5. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
  6. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
  7. package/esm/typings/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +13 -0
  8. package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
  9. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +7 -11
  10. package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +2 -2
  11. package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
  12. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +13 -7
  13. package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +6 -0
  14. package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
  15. package/esm/typings/src/commitments/index.d.ts +2 -1
  16. package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
  17. package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
  18. package/esm/typings/src/types/Message.d.ts +49 -0
  19. package/esm/typings/src/types/typeAliases.d.ts +12 -0
  20. package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
  21. package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
  22. package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
  23. package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
  24. package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
  25. package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
  26. package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
  27. package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
  28. package/esm/typings/src/version.d.ts +1 -1
  29. package/package.json +1 -2
  30. package/umd/index.umd.js +496 -194
  31. package/umd/index.umd.js.map +1 -1
package/umd/index.umd.js CHANGED
@@ -1,15 +1,14 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react'), require('spacetrim'), require('crypto-js'), require('crypto-js/enc-hex'), require('path'), require('crypto'), require('react-dom'), require('@monaco-editor/react'), require('destroyable'), require('highlight.js'), require('katex'), require('showdown'), require('rxjs'), require('waitasecond'), require('crypto-js/sha256'), require('mime-types'), require('papaparse'), require('colors'), require('bottleneck'), require('openai'), require('qrcode')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react', 'spacetrim', 'crypto-js', 'crypto-js/enc-hex', 'path', 'crypto', 'react-dom', '@monaco-editor/react', 'destroyable', 'highlight.js', 'katex', 'showdown', 'rxjs', 'waitasecond', 'crypto-js/sha256', 'mime-types', 'papaparse', 'colors', 'bottleneck', 'openai', 'qrcode'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-components"] = {}, global.jsxRuntime, global.react, global.spaceTrim$1, global.cryptoJs, global.hexEncoder, global.path, global.crypto, global.reactDom, global.Editor, global.destroyable, global.hljs, global.katex, global.showdown, global.rxjs, global.waitasecond, global.sha256, global.mimeTypes, global.papaparse, global.colors, global.Bottleneck, global.OpenAI, global.QRCode));
5
- })(this, (function (exports, jsxRuntime, react, spaceTrim$1, cryptoJs, hexEncoder, path, crypto, reactDom, Editor, destroyable, hljs, katex, showdown, rxjs, waitasecond, sha256, mimeTypes, papaparse, colors, Bottleneck, OpenAI, QRCode) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react'), require('spacetrim'), require('crypto-js'), require('crypto-js/enc-hex'), require('path'), require('crypto'), require('react-dom'), require('@monaco-editor/react'), require('destroyable'), require('katex'), require('react-dom/client'), require('showdown'), require('rxjs'), require('waitasecond'), require('crypto-js/sha256'), require('mime-types'), require('papaparse'), require('colors'), require('bottleneck'), require('openai'), require('qrcode')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react', 'spacetrim', 'crypto-js', 'crypto-js/enc-hex', 'path', 'crypto', 'react-dom', '@monaco-editor/react', 'destroyable', 'katex', 'react-dom/client', 'showdown', 'rxjs', 'waitasecond', 'crypto-js/sha256', 'mime-types', 'papaparse', 'colors', 'bottleneck', 'openai', 'qrcode'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-components"] = {}, global.jsxRuntime, global.react, global.spaceTrim$1, global.cryptoJs, global.hexEncoder, global.path, global.crypto, global.reactDom, global.Editor, global.destroyable, global.katex, global.client, global.showdown, global.rxjs, global.waitasecond, global.sha256, global.mimeTypes, global.papaparse, global.colors, global.Bottleneck, global.OpenAI, global.QRCode));
5
+ })(this, (function (exports, jsxRuntime, react, spaceTrim$1, cryptoJs, hexEncoder, path, crypto, reactDom, Editor, destroyable, katex, client, showdown, rxjs, waitasecond, sha256, mimeTypes, papaparse, colors, Bottleneck, OpenAI, QRCode) { 'use strict';
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
9
  var spaceTrim__default = /*#__PURE__*/_interopDefaultLegacy(spaceTrim$1);
10
10
  var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
11
11
  var Editor__default = /*#__PURE__*/_interopDefaultLegacy(Editor);
12
- var hljs__default = /*#__PURE__*/_interopDefaultLegacy(hljs);
13
12
  var katex__default = /*#__PURE__*/_interopDefaultLegacy(katex);
14
13
  var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
15
14
  var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
@@ -31,7 +30,7 @@
31
30
  * @generated
32
31
  * @see https://github.com/webgptorg/promptbook
33
32
  */
34
- const PROMPTBOOK_ENGINE_VERSION = '0.104.0-1';
33
+ const PROMPTBOOK_ENGINE_VERSION = '0.104.0-3';
35
34
  /**
36
35
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
37
36
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -80,9 +79,9 @@
80
79
  }
81
80
  }
82
81
 
83
- var css_248z$9 = ".AvatarChip-module_AvatarChip__4sA0u{align-items:center;background:#e0e7ef;border:1px solid #b3c2d1;border-radius:16px;color:#2a3b4d;cursor:pointer;display:inline-flex;font-size:.95em;font-weight:500;margin:2px;padding:4px 12px}.AvatarChip-module_Avatar__mN2sc{border-radius:50%;height:24px;margin-right:8px;object-fit:cover;width:24px}.AvatarChip-module_TemplateLabel__-7vVI{background:#f0f4f8;border-radius:12px;color:#3a4752;font-size:.8em;margin-left:8px;margin-right:0;padding:2px 6px;text-transform:uppercase}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkF2YXRhckNoaXAubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxrQkFBbUIsQ0FHbkIsa0JBQW1CLENBS25CLHdCQUF5QixDQU56QixrQkFBbUIsQ0FFbkIsYUFBYyxDQU1kLGNBQWUsQ0FYZixtQkFBb0IsQ0FPcEIsZUFBaUIsQ0FEakIsZUFBZ0IsQ0FFaEIsVUFBVyxDQU5YLGdCQVVKLENBRUEsaUNBR0ksaUJBQWtCLENBRGxCLFdBQVksQ0FHWixnQkFBaUIsQ0FEakIsZ0JBQWlCLENBSGpCLFVBS0osQ0FFQSx3Q0FDSSxrQkFBbUIsQ0FJbkIsa0JBQW1CLENBSG5CLGFBQWMsQ0FDZCxjQUFnQixDQUdoQixlQUFnQixDQUNoQixjQUFlLENBSGYsZUFBZ0IsQ0FJaEIsd0JBQ0oiLCJmaWxlIjoiQXZhdGFyQ2hpcC5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkF2YXRhckNoaXAge1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgcGFkZGluZzogNHB4IDEycHg7XG4gICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICBiYWNrZ3JvdW5kOiAjZTBlN2VmO1xuICAgIGNvbG9yOiAjMmEzYjRkO1xuICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgZm9udC1zaXplOiAwLjk1ZW07XG4gICAgbWFyZ2luOiAycHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2IzYzJkMTtcblxuICAgIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLkF2YXRhciB7XG4gICAgd2lkdGg6IDI0cHg7XG4gICAgaGVpZ2h0OiAyNHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBvYmplY3QtZml0OiBjb3ZlcjtcbiAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbn1cblxuLlRlbXBsYXRlTGFiZWwge1xuICAgIGJhY2tncm91bmQ6ICNmMGY0Zjg7XG4gICAgY29sb3I6ICMzYTQ3NTI7XG4gICAgZm9udC1zaXplOiAwLjhlbTtcbiAgICBwYWRkaW5nOiAycHggNnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICBtYXJnaW4tcmlnaHQ6IDA7XG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbn1cbiJdfQ== */";
84
- var styles$8 = {"AvatarChip":"AvatarChip-module_AvatarChip__4sA0u","Avatar":"AvatarChip-module_Avatar__mN2sc","TemplateLabel":"AvatarChip-module_TemplateLabel__-7vVI"};
85
- styleInject(css_248z$9);
82
+ var css_248z$a = ".AvatarChip-module_AvatarChip__4sA0u{align-items:center;background:#e0e7ef;border:1px solid #b3c2d1;border-radius:16px;color:#2a3b4d;cursor:pointer;display:inline-flex;font-size:.95em;font-weight:500;margin:2px;padding:4px 12px}.AvatarChip-module_Avatar__mN2sc{border-radius:50%;height:24px;margin-right:8px;object-fit:cover;width:24px}.AvatarChip-module_TemplateLabel__-7vVI{background:#f0f4f8;border-radius:12px;color:#3a4752;font-size:.8em;margin-left:8px;margin-right:0;padding:2px 6px;text-transform:uppercase}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkF2YXRhckNoaXAubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxrQkFBbUIsQ0FHbkIsa0JBQW1CLENBS25CLHdCQUF5QixDQU56QixrQkFBbUIsQ0FFbkIsYUFBYyxDQU1kLGNBQWUsQ0FYZixtQkFBb0IsQ0FPcEIsZUFBaUIsQ0FEakIsZUFBZ0IsQ0FFaEIsVUFBVyxDQU5YLGdCQVVKLENBRUEsaUNBR0ksaUJBQWtCLENBRGxCLFdBQVksQ0FHWixnQkFBaUIsQ0FEakIsZ0JBQWlCLENBSGpCLFVBS0osQ0FFQSx3Q0FDSSxrQkFBbUIsQ0FJbkIsa0JBQW1CLENBSG5CLGFBQWMsQ0FDZCxjQUFnQixDQUdoQixlQUFnQixDQUNoQixjQUFlLENBSGYsZUFBZ0IsQ0FJaEIsd0JBQ0oiLCJmaWxlIjoiQXZhdGFyQ2hpcC5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkF2YXRhckNoaXAge1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgcGFkZGluZzogNHB4IDEycHg7XG4gICAgYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICBiYWNrZ3JvdW5kOiAjZTBlN2VmO1xuICAgIGNvbG9yOiAjMmEzYjRkO1xuICAgIGZvbnQtd2VpZ2h0OiA1MDA7XG4gICAgZm9udC1zaXplOiAwLjk1ZW07XG4gICAgbWFyZ2luOiAycHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2IzYzJkMTtcblxuICAgIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLkF2YXRhciB7XG4gICAgd2lkdGg6IDI0cHg7XG4gICAgaGVpZ2h0OiAyNHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICBvYmplY3QtZml0OiBjb3ZlcjtcbiAgICBtYXJnaW4tcmlnaHQ6IDhweDtcbn1cblxuLlRlbXBsYXRlTGFiZWwge1xuICAgIGJhY2tncm91bmQ6ICNmMGY0Zjg7XG4gICAgY29sb3I6ICMzYTQ3NTI7XG4gICAgZm9udC1zaXplOiAwLjhlbTtcbiAgICBwYWRkaW5nOiAycHggNnB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgbWFyZ2luLWxlZnQ6IDhweDtcbiAgICBtYXJnaW4tcmlnaHQ6IDA7XG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbn1cbiJdfQ== */";
83
+ var styles$9 = {"AvatarChip":"AvatarChip-module_AvatarChip__4sA0u","Avatar":"AvatarChip-module_Avatar__mN2sc","TemplateLabel":"AvatarChip-module_TemplateLabel__-7vVI"};
84
+ styleInject(css_248z$a);
86
85
 
87
86
  /**
88
87
  * Shows a chip with avatar's avatar and name
@@ -92,7 +91,7 @@
92
91
  function AvatarChip(props) {
93
92
  const { avatarBasicInformation, className, onSelect, isSelected, isTemplate } = props;
94
93
  const { agentName, meta } = avatarBasicInformation;
95
- return (jsxRuntime.jsxs("div", { className: classNames(styles$8.AvatarChip, className, isSelected ? styles$8.Selected : undefined), onClick: () => onSelect === null || onSelect === void 0 ? void 0 : onSelect(avatarBasicInformation), style: { cursor: onSelect ? 'pointer' : undefined }, children: [jsxRuntime.jsx("img", { src: meta.image, alt: agentName || '', className: styles$8.Avatar }), meta.fullname || agentName, isTemplate && jsxRuntime.jsx("span", { className: styles$8.TemplateLabel, children: "Template" })] }));
94
+ return (jsxRuntime.jsxs("div", { className: classNames(styles$9.AvatarChip, className, isSelected ? styles$9.Selected : undefined), onClick: () => onSelect === null || onSelect === void 0 ? void 0 : onSelect(avatarBasicInformation), style: { cursor: onSelect ? 'pointer' : undefined }, children: [jsxRuntime.jsx("img", { src: meta.image, alt: agentName || '', className: styles$9.Avatar }), meta.fullname || agentName, isTemplate && jsxRuntime.jsx("span", { className: styles$9.TemplateLabel, children: "Template" })] }));
96
95
  }
97
96
 
98
97
  /**
@@ -3043,13 +3042,14 @@
3043
3042
  *
3044
3043
  * @public exported from `@promptbook/utils`
3045
3044
  */
3046
- const $isRunningInBrowser = new Function(`
3047
- try {
3048
- return this === window;
3049
- } catch (e) {
3050
- return false;
3045
+ function $isRunningInBrowser() {
3046
+ try {
3047
+ return typeof window !== 'undefined' && typeof window.document !== 'undefined';
3048
+ }
3049
+ catch (e) {
3050
+ return false;
3051
+ }
3051
3052
  }
3052
- `);
3053
3053
  /**
3054
3054
  * TODO: [🎺]
3055
3055
  */
@@ -3061,13 +3061,15 @@
3061
3061
  *
3062
3062
  * @public exported from `@promptbook/utils`
3063
3063
  */
3064
- const $isRunningInJest = new Function(`
3065
- try {
3066
- return process.env.JEST_WORKER_ID !== undefined;
3067
- } catch (e) {
3068
- return false;
3064
+ function $isRunningInJest() {
3065
+ var _a;
3066
+ try {
3067
+ return typeof process !== 'undefined' && ((_a = process.env) === null || _a === void 0 ? void 0 : _a.JEST_WORKER_ID) !== undefined;
3068
+ }
3069
+ catch (e) {
3070
+ return false;
3071
+ }
3069
3072
  }
3070
- `);
3071
3073
  /**
3072
3074
  * TODO: [🎺]
3073
3075
  */
@@ -3079,13 +3081,14 @@
3079
3081
  *
3080
3082
  * @public exported from `@promptbook/utils`
3081
3083
  */
3082
- const $isRunningInNode = new Function(`
3083
- try {
3084
- return this === global;
3085
- } catch (e) {
3086
- return false;
3084
+ function $isRunningInNode() {
3085
+ try {
3086
+ return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
3087
+ }
3088
+ catch (e) {
3089
+ return false;
3090
+ }
3087
3091
  }
3088
- `);
3089
3092
  /**
3090
3093
  * TODO: [🎺]
3091
3094
  */
@@ -3097,17 +3100,17 @@
3097
3100
  *
3098
3101
  * @public exported from `@promptbook/utils`
3099
3102
  */
3100
- const $isRunningInWebWorker = new Function(`
3101
- try {
3102
- if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
3103
- return true;
3104
- } else {
3103
+ function $isRunningInWebWorker() {
3104
+ try {
3105
+ // Note: Check for importScripts which is specific to workers
3106
+ // and not available in the main browser thread
3107
+ return (typeof self !== 'undefined' &&
3108
+ typeof self.importScripts === 'function');
3109
+ }
3110
+ catch (e) {
3105
3111
  return false;
3106
3112
  }
3107
- } catch (e) {
3108
- return false;
3109
3113
  }
3110
- `);
3111
3114
  /**
3112
3115
  * TODO: [🎺]
3113
3116
  */
@@ -4123,6 +4126,114 @@
4123
4126
  * Note: [💞] Ignore a discrepancy between file name and entity name
4124
4127
  */
4125
4128
 
4129
+ /**
4130
+ * DICTIONARY commitment definition
4131
+ *
4132
+ * The DICTIONARY commitment defines specific terms and their meanings that the agent should use correctly
4133
+ * in its reasoning and responses. This ensures consistent terminology usage.
4134
+ *
4135
+ * Key features:
4136
+ * - Multiple DICTIONARY commitments are automatically merged into one
4137
+ * - Content is placed in a dedicated section of the system message
4138
+ * - Terms and definitions are stored in metadata.DICTIONARY for debugging
4139
+ * - Agent should use the defined terms correctly in responses
4140
+ *
4141
+ * Example usage in agent source:
4142
+ *
4143
+ * ```book
4144
+ * Legal Assistant
4145
+ *
4146
+ * PERSONA You are a knowledgeable legal assistant
4147
+ * DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
4148
+ * DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
4149
+ * DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
4150
+ * ```
4151
+ *
4152
+ * @private [🪔] Maybe export the commitments through some package
4153
+ */
4154
+ class DictionaryCommitmentDefinition extends BaseCommitmentDefinition {
4155
+ constructor() {
4156
+ super('DICTIONARY');
4157
+ }
4158
+ /**
4159
+ * Short one-line description of DICTIONARY.
4160
+ */
4161
+ get description() {
4162
+ return 'Define terms and their meanings for consistent terminology usage.';
4163
+ }
4164
+ /**
4165
+ * Icon for this commitment.
4166
+ */
4167
+ get icon() {
4168
+ return '📚';
4169
+ }
4170
+ /**
4171
+ * Markdown documentation for DICTIONARY commitment.
4172
+ */
4173
+ get documentation() {
4174
+ return spaceTrim$1.spaceTrim(`
4175
+ # DICTIONARY
4176
+
4177
+ Defines specific terms and their meanings that the agent should use correctly in reasoning and responses.
4178
+
4179
+ ## Key aspects
4180
+
4181
+ - Multiple \`DICTIONARY\` commitments are merged together.
4182
+ - Terms are defined in the format: "Term is definition"
4183
+ - The agent should use these terms consistently in responses.
4184
+ - Definitions help ensure accurate and consistent terminology.
4185
+
4186
+ ## Examples
4187
+
4188
+ \`\`\`book
4189
+ Legal Assistant
4190
+
4191
+ PERSONA You are a knowledgeable legal assistant specializing in criminal law
4192
+ DICTIONARY Misdemeanor is a minor wrongdoing or criminal offense
4193
+ DICTIONARY Felony is a serious crime usually punishable by imprisonment for more than one year
4194
+ DICTIONARY Tort is a civil wrong that causes harm or loss to another person, leading to legal liability
4195
+ \`\`\`
4196
+
4197
+ \`\`\`book
4198
+ Medical Assistant
4199
+
4200
+ PERSONA You are a helpful medical assistant
4201
+ DICTIONARY Hypertension is persistently high blood pressure
4202
+ DICTIONARY Diabetes is a chronic condition that affects how the body processes blood sugar
4203
+ DICTIONARY Vaccine is a biological preparation that provides active immunity to a particular disease
4204
+ \`\`\`
4205
+ `);
4206
+ }
4207
+ applyToAgentModelRequirements(requirements, content) {
4208
+ var _a;
4209
+ const trimmedContent = content.trim();
4210
+ if (!trimmedContent) {
4211
+ return requirements;
4212
+ }
4213
+ // Get existing dictionary entries from metadata
4214
+ const existingDictionary = ((_a = requirements.metadata) === null || _a === void 0 ? void 0 : _a.DICTIONARY) || '';
4215
+ // Merge the new dictionary entry with existing entries
4216
+ const mergedDictionary = existingDictionary
4217
+ ? `${existingDictionary}\n${trimmedContent}`
4218
+ : trimmedContent;
4219
+ // Store the merged dictionary in metadata for debugging and inspection
4220
+ const updatedMetadata = {
4221
+ ...requirements.metadata,
4222
+ DICTIONARY: mergedDictionary,
4223
+ };
4224
+ // Create the dictionary section for the system message
4225
+ // Format: "# DICTIONARY\nTerm: definition\nTerm: definition..."
4226
+ const dictionarySection = `# DICTIONARY\n${mergedDictionary}`;
4227
+ return {
4228
+ ...this.appendToSystemMessage(requirements, dictionarySection),
4229
+ metadata: updatedMetadata,
4230
+ };
4231
+ }
4232
+ }
4233
+ /**
4234
+ * Note: [💞] Ignore a discrepancy between file name and entity name
4235
+ */
4236
+
4126
4237
  /**
4127
4238
  * FORMAT commitment definition
4128
4239
  *
@@ -6943,6 +7054,7 @@
6943
7054
  new DeleteCommitmentDefinition('CANCEL'),
6944
7055
  new DeleteCommitmentDefinition('DISCARD'),
6945
7056
  new DeleteCommitmentDefinition('REMOVE'),
7057
+ new DictionaryCommitmentDefinition(),
6946
7058
  new OpenCommitmentDefinition(),
6947
7059
  new ClosedCommitmentDefinition(),
6948
7060
  new UseBrowserCommitmentDefinition(),
@@ -7002,17 +7114,64 @@
7002
7114
  };
7003
7115
  }
7004
7116
  const lines = agentSource.split('\n');
7005
- const agentName = (((_a = lines[0]) === null || _a === void 0 ? void 0 : _a.trim()) || null);
7117
+ let agentName = null;
7118
+ let agentNameLineIndex = -1;
7119
+ // Find the agent name: first non-empty line that is not a commitment and not a horizontal line
7120
+ for (let i = 0; i < lines.length; i++) {
7121
+ const line = lines[i];
7122
+ if (line === undefined) {
7123
+ continue;
7124
+ }
7125
+ const trimmed = line.trim();
7126
+ if (!trimmed) {
7127
+ continue;
7128
+ }
7129
+ const isHorizontal = HORIZONTAL_LINE_PATTERN.test(line);
7130
+ if (isHorizontal) {
7131
+ continue;
7132
+ }
7133
+ let isCommitment = false;
7134
+ for (const definition of COMMITMENT_REGISTRY) {
7135
+ const typeRegex = definition.createTypeRegex();
7136
+ const match = typeRegex.exec(trimmed);
7137
+ if (match && ((_a = match.groups) === null || _a === void 0 ? void 0 : _a.type)) {
7138
+ isCommitment = true;
7139
+ break;
7140
+ }
7141
+ }
7142
+ if (!isCommitment) {
7143
+ agentName = trimmed;
7144
+ agentNameLineIndex = i;
7145
+ break;
7146
+ }
7147
+ }
7006
7148
  const commitments = [];
7007
7149
  const nonCommitmentLines = [];
7008
- // Always add the first line (agent name) to non-commitment lines
7009
- if (lines[0] !== undefined) {
7010
- nonCommitmentLines.push(lines[0]);
7150
+ // Add lines before agentName that are horizontal lines (they are non-commitment)
7151
+ for (let i = 0; i < agentNameLineIndex; i++) {
7152
+ const line = lines[i];
7153
+ if (line === undefined) {
7154
+ continue;
7155
+ }
7156
+ const trimmed = line.trim();
7157
+ if (!trimmed) {
7158
+ continue;
7159
+ }
7160
+ const isHorizontal = HORIZONTAL_LINE_PATTERN.test(line);
7161
+ if (isHorizontal) {
7162
+ nonCommitmentLines.push(line);
7163
+ }
7164
+ // Note: Commitments before agentName are not added to nonCommitmentLines
7165
+ }
7166
+ // Add the agent name line to non-commitment lines
7167
+ if (agentNameLineIndex >= 0) {
7168
+ nonCommitmentLines.push(lines[agentNameLineIndex]);
7011
7169
  }
7012
7170
  // Parse commitments with multiline support
7013
7171
  let currentCommitment = null;
7014
- // Process lines starting from the second line (skip agent name)
7015
- for (let i = 1; i < lines.length; i++) {
7172
+ // Process lines starting from after the agent name line
7173
+ const startIndex = agentNameLineIndex >= 0 ? agentNameLineIndex + 1 : 0;
7174
+ for (let i = startIndex; i < lines.length; i++) {
7016
7175
  const line = lines[i];
7017
7176
  if (line === undefined) {
7018
7177
  continue;
@@ -7234,6 +7393,7 @@
7234
7393
  return {
7235
7394
  agentName: normalizeAgentName(parseResult.agentName || createDefaultAgentName(agentSource)),
7236
7395
  agentHash,
7396
+ permanentId: meta.id,
7237
7397
  personaDescription,
7238
7398
  initialMessage,
7239
7399
  meta,
@@ -7273,9 +7433,9 @@
7273
7433
  return jsxRuntime.jsx(AvatarChip, { avatarBasicInformation: avatarBasicInformation, ...props });
7274
7434
  }
7275
7435
 
7276
- var css_248z$8 = ".Modal-module_scrim__jKO-A{align-items:center;background-color:rgba(0,0,0,.5);display:flex;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:9000000}.Modal-module_Modal__k49dY{background:#fff;border-radius:8px;max-height:90%;max-width:90%;min-height:30vh;min-width:50vw;overflow:auto;padding:20px;position:relative}.Modal-module_closeButton__dzf6l{background:transparent;border:none;cursor:pointer;font-size:24px;position:absolute;right:10px;top:10px}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk1vZGFsLm1vZHVsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMkJBU0ksa0JBQW1CLENBSG5CLCtCQUFvQyxDQUNwQyxZQUFhLENBRmIsV0FBWSxDQUdaLHNCQUF1QixDQUx2QixNQUFPLENBRlAsY0FBZSxDQUNmLEtBQU0sQ0FFTixVQUFXLENBTVgsZUFDSixDQUVBLDJCQUNJLGVBQWlCLENBRWpCLGlCQUFrQixDQUdsQixjQUFlLENBRGYsYUFBYyxDQUdkLGVBQWdCLENBRGhCLGNBQWUsQ0FFZixhQUFjLENBUGQsWUFBYSxDQUViLGlCQU1KLENBRUEsaUNBSUksc0JBQXVCLENBQ3ZCLFdBQVksQ0FFWixjQUFlLENBRGYsY0FBZSxDQUxmLGlCQUFrQixDQUVsQixVQUFXLENBRFgsUUFNSiIsImZpbGUiOiJNb2RhbC5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLnNjcmltIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgei1pbmRleDogOTAwMDAwMDtcbn1cblxuLk1vZGFsIHtcbiAgICBiYWNrZ3JvdW5kOiB3aGl0ZTtcbiAgICBwYWRkaW5nOiAyMHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWF4LXdpZHRoOiA5MCU7XG4gICAgbWF4LWhlaWdodDogOTAlO1xuICAgIG1pbi13aWR0aDogNTB2dztcbiAgICBtaW4taGVpZ2h0OiAzMHZoO1xuICAgIG92ZXJmbG93OiBhdXRvO1xufVxuXG4uY2xvc2VCdXR0b24ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDEwcHg7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGZvbnQtc2l6ZTogMjRweDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG59XG4iXX0= */";
7277
- var styles$7 = {"scrim":"Modal-module_scrim__jKO-A","Modal":"Modal-module_Modal__k49dY","closeButton":"Modal-module_closeButton__dzf6l"};
7278
- styleInject(css_248z$8);
7436
+ var css_248z$9 = ".Modal-module_scrim__jKO-A{align-items:center;background-color:rgba(0,0,0,.5);display:flex;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:9000000}.Modal-module_Modal__k49dY{background:#fff;border-radius:8px;max-height:90%;max-width:90%;min-height:30vh;min-width:50vw;overflow:auto;padding:20px;position:relative}.Modal-module_closeButton__dzf6l{background:transparent;border:none;cursor:pointer;font-size:24px;position:absolute;right:10px;top:10px}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk1vZGFsLm1vZHVsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsMkJBU0ksa0JBQW1CLENBSG5CLCtCQUFvQyxDQUNwQyxZQUFhLENBRmIsV0FBWSxDQUdaLHNCQUF1QixDQUx2QixNQUFPLENBRlAsY0FBZSxDQUNmLEtBQU0sQ0FFTixVQUFXLENBTVgsZUFDSixDQUVBLDJCQUNJLGVBQWlCLENBRWpCLGlCQUFrQixDQUdsQixjQUFlLENBRGYsYUFBYyxDQUdkLGVBQWdCLENBRGhCLGNBQWUsQ0FFZixhQUFjLENBUGQsWUFBYSxDQUViLGlCQU1KLENBRUEsaUNBSUksc0JBQXVCLENBQ3ZCLFdBQVksQ0FFWixjQUFlLENBRGYsY0FBZSxDQUxmLGlCQUFrQixDQUVsQixVQUFXLENBRFgsUUFNSiIsImZpbGUiOiJNb2RhbC5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLnNjcmltIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgei1pbmRleDogOTAwMDAwMDtcbn1cblxuLk1vZGFsIHtcbiAgICBiYWNrZ3JvdW5kOiB3aGl0ZTtcbiAgICBwYWRkaW5nOiAyMHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWF4LXdpZHRoOiA5MCU7XG4gICAgbWF4LWhlaWdodDogOTAlO1xuICAgIG1pbi13aWR0aDogNTB2dztcbiAgICBtaW4taGVpZ2h0OiAzMHZoO1xuICAgIG92ZXJmbG93OiBhdXRvO1xufVxuXG4uY2xvc2VCdXR0b24ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDEwcHg7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgYm9yZGVyOiBub25lO1xuICAgIGZvbnQtc2l6ZTogMjRweDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG59XG4iXX0= */";
7437
+ var styles$8 = {"scrim":"Modal-module_scrim__jKO-A","Modal":"Modal-module_Modal__k49dY","closeButton":"Modal-module_closeButton__dzf6l"};
7438
+ styleInject(css_248z$9);
7279
7439
 
7280
7440
  /**
7281
7441
  *
@@ -7293,7 +7453,7 @@
7293
7453
  window.removeEventListener('keydown', handleKeyDown);
7294
7454
  };
7295
7455
  }, [onClose]);
7296
- return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$7.scrim, onClick: onClose, children: jsxRuntime.jsxs("div", { className: classNames(styles$7.Modal, className), onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsx("button", { className: styles$7.closeButton, onClick: onClose, children: "\u00D7" }), children] }) }), document.body);
7456
+ return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$8.scrim, onClick: onClose, children: jsxRuntime.jsxs("div", { className: classNames(styles$8.Modal, className), onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsx("button", { className: styles$8.closeButton, onClick: onClose, children: "\u00D7" }), children] }) }), document.body);
7297
7457
  }
7298
7458
 
7299
7459
  /**
@@ -7378,9 +7538,9 @@
7378
7538
  // <- [🐱‍🚀] Buttons into genesis book
7379
7539
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
7380
7540
 
7381
- var css_248z$7 = ".BookEditor-module_BookEditor__s-0PU{width:100%}.BookEditor-module_bookEditorContainer__wLMwM{box-sizing:border-box;height:100%;padding:10px 25px 0;position:relative;width:100%}.BookEditor-module_bookEditorContainer__wLMwM.BookEditor-module_isVerbose__VQ6iL{background-color:rgba(0,0,0,.05);outline:1px dotted rgba(0,0,0,.5)}.BookEditor-module_isVerbose__VQ6iL{outline:2px dotted #ff7526}.BookEditor-module_bookEditorWrapper__twppD{background-color:#fff;border:1px solid rgba(209,213,219,.8);border-radius:1rem;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);overflow:hidden;padding-top:10px;transition:box-shadow .2s ease-in-out}.BookEditor-module_isVerbose__VQ6iL .BookEditor-module_bookEditorWrapper__twppD{overflow:visible}.BookEditor-module_bookEditorWrapper__twppD:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.BookEditor-module_bookEditorWrapper__twppD.BookEditor-module_isBorderRadiusDisabled__h1I3v{border-radius:0}.BookEditor-module_dropOverlay__xWWoX{align-items:center;background-color:rgba(0,0,0,.5);bottom:0;color:#fff;display:flex;font-size:1.5rem;justify-content:center;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:100}.BookEditor-module_bookEditorActionbar__KW6dc{position:absolute;right:55px;top:10px;z-index:100}.BookEditor-module_fullscreen__rktsl{border:none;border-radius:0;bottom:0;box-shadow:none;height:100%;left:0;padding-top:50px;position:fixed;right:0;top:0;width:100%;z-index:9999}.BookEditor-module_button__hS390{align-items:center;background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);color:#374151;cursor:pointer;display:inline-flex;gap:.5rem;padding:.5rem 1rem;transition:all .2s ease-in-out}.BookEditor-module_button__hS390:hover{background-color:#f9fafb;border-color:#b7bcce;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkJvb2tFZGl0b3IubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxVQUNKLENBRUEsOENBS0kscUJBQXNCLENBSHRCLFdBQVksQ0FFWixtQkFBb0IsQ0FEcEIsaUJBQWtCLENBRmxCLFVBS0osQ0FFQSxpRkFFSSxnQ0FBcUMsQ0FDckMsaUNBRUosQ0FFQSxvQ0FDSSwwQkFDSixDQUVBLDRDQUtJLHFCQUF1QixDQUR2QixxQ0FBMEMsQ0FGMUMsa0JBQW1CLENBSW5CLHNDQUEyQyxDQUwzQyxlQUFnQixDQUVoQixnQkFBaUIsQ0FJakIscUNBQ0osQ0FDQSxnRkFFSSxnQkFFSixDQUVBLGtEQUNJLHVFQUNKLENBVUEsNEZBQ0ksZUFDSixDQUVBLHNDQVNJLGtCQUFtQixDQUhuQiwrQkFBb0MsQ0FEcEMsUUFBUyxDQUVULFVBQVksQ0FDWixZQUFhLENBR2IsZ0JBQWlCLENBRGpCLHNCQUF1QixDQVB2QixNQUFPLENBVVAsbUJBQW9CLENBWnBCLGlCQUFrQixDQUdsQixPQUFRLENBRlIsS0FBTSxDQVVOLFdBRUosQ0FRQSw4Q0FDSSxpQkFBa0IsQ0FFbEIsVUFBVyxDQURYLFFBQVMsQ0FFVCxXQUNKLENBRUEscUNBV0ksV0FBWSxDQUZaLGVBQWdCLENBSmhCLFFBQVMsQ0FPVCxlQUFnQixDQUxoQixXQUFZLENBSlosTUFBTyxDQU9QLGdCQUFpQixDQVRqQixjQUFlLENBR2YsT0FBUSxDQUZSLEtBQU0sQ0FJTixVQUFXLENBRVgsWUFLSixDQUVBLGlDQU9JLGtCQUFtQixDQU5uQixxQkFBc0IsQ0FDdEIsd0JBQXlCLENBQ3pCLHFCQUF1QixDQU92QixzQ0FBMkMsQ0FEM0MsYUFBYyxDQUpkLGNBQWUsQ0FDZixtQkFBb0IsQ0FFcEIsU0FBVyxDQUpYLGtCQUFvQixDQU9wQiw4QkFDSixDQUVBLHVDQUNJLHdCQUF5QixDQUN6QixvQkFBcUIsQ0FDckIsaUVBQ0oiLCJmaWxlIjoiQm9va0VkaXRvci5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkJvb2tFZGl0b3Ige1xuICAgIC8qIGhlaWdodDogNDUwcHg7ICovXG4gICAgd2lkdGg6IDEwMCU7XG59XG5cbi5ib29rRWRpdG9yQ29udGFpbmVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDEwcHggMjVweCAwO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbi5ib29rRWRpdG9yQ29udGFpbmVyLmlzVmVyYm9zZSB7XG4gICAgLyoqL1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4wNSk7XG4gICAgb3V0bGluZTogMXB4IGRvdHRlZCByZ2JhKDAsIDAsIDAsIDAuNSk7XG4gICAgLyoqL1xufVxuXG4uaXNWZXJib3NlIHtcbiAgICBvdXRsaW5lOiAycHggZG90dGVkIHJnYigyNTUgMTE3IDM4KTtcbn1cblxuLmJvb2tFZGl0b3JXcmFwcGVyIHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIGJvcmRlci1yYWRpdXM6IDFyZW07XG4gICAgcGFkZGluZy10b3A6IDEwcHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMDksIDIxMywgMjE5LCAwLjgpO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICAgIGJveC1zaGFkb3c6IDAgMXB4IDJweCAwIHJnYmEoMCwgMCwgMCwgMC4wNSk7XG4gICAgdHJhbnNpdGlvbjogYm94LXNoYWRvdyAwLjJzIGVhc2UtaW4tb3V0O1xufVxuLmlzVmVyYm9zZSAuYm9va0VkaXRvcldyYXBwZXIge1xuICAgIC8qKi9cbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcbiAgICAvKiovXG59XG5cbi5ib29rRWRpdG9yV3JhcHBlcjpob3ZlciB7XG4gICAgYm94LXNoYWRvdzogMCA0cHggNnB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDJweCA0cHggLTFweCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXI6Zm9jdXMtd2l0aGluIHtcbiAgICAvKlxuICAgIG91dGxpbmU6IDJweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDNweCByZ2JhKDk5LCAxMDIsIDI0MSwgMC40KTtcbiAgICAqL1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIuaXNCb3JkZXJSYWRpdXNEaXNhYmxlZCB7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbn1cblxuLmRyb3BPdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBjb2xvcjogd2hpdGU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGZvbnQtc2l6ZTogMS41cmVtO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLypcbi5ib29rRWRpdG9yQ29udGFpbmVyIDpnbG9iYWwoLnZpZXctbGluZSkge1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWVlOyAvKiA8LSBOb3RlOiBgUFJPTVBUQk9PS19TWU5UQVhfQ09MT1JTLkxJTkVgICogL1xufVxuKi9cblxuLmJvb2tFZGl0b3JBY3Rpb25iYXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDU1cHg7XG4gICAgei1pbmRleDogMTAwO1xufVxuXG4uZnVsbHNjcmVlbiB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogOTk5OTtcbiAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgIHBhZGRpbmctdG9wOiA1MHB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xufVxuXG4uYnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNkMWQ1ZGI7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zNzVyZW07XG4gICAgcGFkZGluZzogMC41cmVtIDFyZW07XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAwLjVyZW07XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlLWluLW91dDtcbn1cblxuLmJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZmFmYjtcbiAgICBib3JkZXItY29sb3I6ICNiN2JjY2U7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IDAgcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDFweCAycHggMCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuIl19 */";
7382
- var styles$6 = {"BookEditor":"BookEditor-module_BookEditor__s-0PU","bookEditorContainer":"BookEditor-module_bookEditorContainer__wLMwM","isVerbose":"BookEditor-module_isVerbose__VQ6iL","bookEditorWrapper":"BookEditor-module_bookEditorWrapper__twppD","isBorderRadiusDisabled":"BookEditor-module_isBorderRadiusDisabled__h1I3v","dropOverlay":"BookEditor-module_dropOverlay__xWWoX","bookEditorActionbar":"BookEditor-module_bookEditorActionbar__KW6dc","fullscreen":"BookEditor-module_fullscreen__rktsl","button":"BookEditor-module_button__hS390"};
7383
- styleInject(css_248z$7);
7541
+ var css_248z$8 = ".BookEditor-module_BookEditor__s-0PU{width:100%}.BookEditor-module_bookEditorContainer__wLMwM{box-sizing:border-box;height:100%;padding:10px 25px 0;position:relative;width:100%}.BookEditor-module_bookEditorContainer__wLMwM.BookEditor-module_isVerbose__VQ6iL{background-color:rgba(0,0,0,.05);outline:1px dotted rgba(0,0,0,.5)}.BookEditor-module_isVerbose__VQ6iL{outline:2px dotted #ff7526}.BookEditor-module_bookEditorWrapper__twppD{background-color:#fff;border:1px solid rgba(209,213,219,.8);border-radius:1rem;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);overflow:hidden;padding-top:10px;transition:box-shadow .2s ease-in-out}.BookEditor-module_isVerbose__VQ6iL .BookEditor-module_bookEditorWrapper__twppD{overflow:visible}.BookEditor-module_bookEditorWrapper__twppD:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.BookEditor-module_bookEditorWrapper__twppD.BookEditor-module_isBorderRadiusDisabled__h1I3v{border-radius:0}.BookEditor-module_dropOverlay__xWWoX{align-items:center;background-color:rgba(0,0,0,.5);bottom:0;color:#fff;display:flex;font-size:1.5rem;justify-content:center;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:100}.BookEditor-module_bookEditorActionbar__KW6dc{position:absolute;right:55px;top:10px;z-index:100}.BookEditor-module_fullscreen__rktsl{border:none;border-radius:0;bottom:0;box-shadow:none;height:100%;left:0;padding-top:50px;position:fixed;right:0;top:0;width:100%;z-index:9999}.BookEditor-module_button__hS390{align-items:center;background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);color:#374151;cursor:pointer;display:inline-flex;gap:.5rem;padding:.5rem 1rem;transition:all .2s ease-in-out}.BookEditor-module_button__hS390:hover{background-color:#f9fafb;border-color:#b7bcce;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkJvb2tFZGl0b3IubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxVQUNKLENBRUEsOENBS0kscUJBQXNCLENBSHRCLFdBQVksQ0FFWixtQkFBb0IsQ0FEcEIsaUJBQWtCLENBRmxCLFVBS0osQ0FFQSxpRkFFSSxnQ0FBcUMsQ0FDckMsaUNBRUosQ0FFQSxvQ0FDSSwwQkFDSixDQUVBLDRDQUtJLHFCQUF1QixDQUR2QixxQ0FBMEMsQ0FGMUMsa0JBQW1CLENBSW5CLHNDQUEyQyxDQUwzQyxlQUFnQixDQUVoQixnQkFBaUIsQ0FJakIscUNBQ0osQ0FDQSxnRkFFSSxnQkFFSixDQUVBLGtEQUNJLHVFQUNKLENBVUEsNEZBQ0ksZUFDSixDQUVBLHNDQVNJLGtCQUFtQixDQUhuQiwrQkFBb0MsQ0FEcEMsUUFBUyxDQUVULFVBQVksQ0FDWixZQUFhLENBR2IsZ0JBQWlCLENBRGpCLHNCQUF1QixDQVB2QixNQUFPLENBVVAsbUJBQW9CLENBWnBCLGlCQUFrQixDQUdsQixPQUFRLENBRlIsS0FBTSxDQVVOLFdBRUosQ0FRQSw4Q0FDSSxpQkFBa0IsQ0FFbEIsVUFBVyxDQURYLFFBQVMsQ0FFVCxXQUNKLENBRUEscUNBV0ksV0FBWSxDQUZaLGVBQWdCLENBSmhCLFFBQVMsQ0FPVCxlQUFnQixDQUxoQixXQUFZLENBSlosTUFBTyxDQU9QLGdCQUFpQixDQVRqQixjQUFlLENBR2YsT0FBUSxDQUZSLEtBQU0sQ0FJTixVQUFXLENBRVgsWUFLSixDQUVBLGlDQU9JLGtCQUFtQixDQU5uQixxQkFBc0IsQ0FDdEIsd0JBQXlCLENBQ3pCLHFCQUF1QixDQU92QixzQ0FBMkMsQ0FEM0MsYUFBYyxDQUpkLGNBQWUsQ0FDZixtQkFBb0IsQ0FFcEIsU0FBVyxDQUpYLGtCQUFvQixDQU9wQiw4QkFDSixDQUVBLHVDQUNJLHdCQUF5QixDQUN6QixvQkFBcUIsQ0FDckIsaUVBQ0oiLCJmaWxlIjoiQm9va0VkaXRvci5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkJvb2tFZGl0b3Ige1xuICAgIC8qIGhlaWdodDogNDUwcHg7ICovXG4gICAgd2lkdGg6IDEwMCU7XG59XG5cbi5ib29rRWRpdG9yQ29udGFpbmVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDEwcHggMjVweCAwO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbi5ib29rRWRpdG9yQ29udGFpbmVyLmlzVmVyYm9zZSB7XG4gICAgLyoqL1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4wNSk7XG4gICAgb3V0bGluZTogMXB4IGRvdHRlZCByZ2JhKDAsIDAsIDAsIDAuNSk7XG4gICAgLyoqL1xufVxuXG4uaXNWZXJib3NlIHtcbiAgICBvdXRsaW5lOiAycHggZG90dGVkIHJnYigyNTUgMTE3IDM4KTtcbn1cblxuLmJvb2tFZGl0b3JXcmFwcGVyIHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIGJvcmRlci1yYWRpdXM6IDFyZW07XG4gICAgcGFkZGluZy10b3A6IDEwcHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMDksIDIxMywgMjE5LCAwLjgpO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICAgIGJveC1zaGFkb3c6IDAgMXB4IDJweCAwIHJnYmEoMCwgMCwgMCwgMC4wNSk7XG4gICAgdHJhbnNpdGlvbjogYm94LXNoYWRvdyAwLjJzIGVhc2UtaW4tb3V0O1xufVxuLmlzVmVyYm9zZSAuYm9va0VkaXRvcldyYXBwZXIge1xuICAgIC8qKi9cbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcbiAgICAvKiovXG59XG5cbi5ib29rRWRpdG9yV3JhcHBlcjpob3ZlciB7XG4gICAgYm94LXNoYWRvdzogMCA0cHggNnB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDJweCA0cHggLTFweCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXI6Zm9jdXMtd2l0aGluIHtcbiAgICAvKlxuICAgIG91dGxpbmU6IDJweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDNweCByZ2JhKDk5LCAxMDIsIDI0MSwgMC40KTtcbiAgICAqL1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIuaXNCb3JkZXJSYWRpdXNEaXNhYmxlZCB7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbn1cblxuLmRyb3BPdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBjb2xvcjogd2hpdGU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGZvbnQtc2l6ZTogMS41cmVtO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLypcbi5ib29rRWRpdG9yQ29udGFpbmVyIDpnbG9iYWwoLnZpZXctbGluZSkge1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWVlOyAvKiA8LSBOb3RlOiBgUFJPTVBUQk9PS19TWU5UQVhfQ09MT1JTLkxJTkVgICogL1xufVxuKi9cblxuLmJvb2tFZGl0b3JBY3Rpb25iYXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDU1cHg7XG4gICAgei1pbmRleDogMTAwO1xufVxuXG4uZnVsbHNjcmVlbiB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogOTk5OTtcbiAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgIHBhZGRpbmctdG9wOiA1MHB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xufVxuXG4uYnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNkMWQ1ZGI7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zNzVyZW07XG4gICAgcGFkZGluZzogMC41cmVtIDFyZW07XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAwLjVyZW07XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlLWluLW91dDtcbn1cblxuLmJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZmFmYjtcbiAgICBib3JkZXItY29sb3I6ICNiN2JjY2U7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IDAgcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDFweCAycHggMCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuIl19 */";
7542
+ var styles$7 = {"BookEditor":"BookEditor-module_BookEditor__s-0PU","bookEditorContainer":"BookEditor-module_bookEditorContainer__wLMwM","isVerbose":"BookEditor-module_isVerbose__VQ6iL","bookEditorWrapper":"BookEditor-module_bookEditorWrapper__twppD","isBorderRadiusDisabled":"BookEditor-module_isBorderRadiusDisabled__h1I3v","dropOverlay":"BookEditor-module_dropOverlay__xWWoX","bookEditorActionbar":"BookEditor-module_bookEditorActionbar__KW6dc","fullscreen":"BookEditor-module_fullscreen__rktsl","button":"BookEditor-module_button__hS390"};
7543
+ styleInject(css_248z$8);
7384
7544
 
7385
7545
  /**
7386
7546
  * Converts Blob, File or MediaSource to url using URL.createObjectURL
@@ -7500,6 +7660,101 @@
7500
7660
  * Note: [🔵] Code in this file should never be published outside of `@promptbook/browser`
7501
7661
  */
7502
7662
 
7663
+ /**
7664
+ * Downloads a file with the given content and filename
7665
+ *
7666
+ * @private utility of `<Chat/>` component
7667
+ */
7668
+ function downloadFile(content, filename, mimeType) {
7669
+ const blob = new Blob([content], { type: mimeType });
7670
+ const url = URL.createObjectURL(blob);
7671
+ const link = document.createElement('a');
7672
+ link.href = url;
7673
+ link.download = filename;
7674
+ document.body.appendChild(link);
7675
+ link.click();
7676
+ document.body.removeChild(link);
7677
+ // Clean up the URL object
7678
+ setTimeout(() => URL.revokeObjectURL(url), 100);
7679
+ }
7680
+
7681
+ var css_248z$7 = ".CodeBlock-module_CodeBlock__6K33Z{border:1px solid #444;border-radius:5px;margin:10px 0;overflow:hidden}.CodeBlock-module_CodeBlockHeader__tfOwl{align-items:center;background-color:#2d2d2d;border-bottom:1px solid #444;color:#ccc;display:flex;font-size:.8em;justify-content:space-between;padding:5px 10px}.CodeBlock-module_CodeBlockButtons__rz1VO{display:flex;gap:8px}.CodeBlock-module_CopyButton__M07tp,.CodeBlock-module_CreateAgentButton__kUEnp,.CodeBlock-module_DownloadButton__ZTrzQ{align-items:center;background:transparent;border:none;color:#aaa;cursor:pointer;display:flex;font-size:inherit;gap:5px;padding:0;transition:color .2s}.CodeBlock-module_CopyButton__M07tp:hover,.CodeBlock-module_CreateAgentButton__kUEnp:hover,.CodeBlock-module_DownloadButton__ZTrzQ:hover{color:#fff}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvZGVCbG9jay5tb2R1bGUuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG1DQUlJLHFCQUFzQixDQUZ0QixpQkFBa0IsQ0FEbEIsYUFBYyxDQUVkLGVBRUosQ0FFQSx5Q0FRSSxrQkFBbUIsQ0FQbkIsd0JBQXlCLENBSXpCLDRCQUE2QixDQUg3QixVQUFXLENBSVgsWUFBYSxDQUZiLGNBQWdCLENBR2hCLDZCQUE4QixDQUo5QixnQkFNSixDQUVBLDBDQUNJLFlBQWEsQ0FDYixPQUNKLENBRUEsdUhBVUksa0JBQW1CLENBUG5CLHNCQUF1QixDQUN2QixXQUFZLENBQ1osVUFBVyxDQUNYLGNBQWUsQ0FHZixZQUFhLENBRmIsaUJBQWtCLENBSWxCLE9BQVEsQ0FIUixTQUFVLENBSVYsb0JBQ0osQ0FFQSx5SUFHSSxVQUNKIiwiZmlsZSI6IkNvZGVCbG9jay5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkNvZGVCbG9jayB7XG4gICAgbWFyZ2luOiAxMHB4IDA7XG4gICAgYm9yZGVyLXJhZGl1czogNXB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm9yZGVyOiAxcHggc29saWQgIzQ0NDsgLyogRGFyayBtb2RlIGJvcmRlciAqL1xufVxuXG4uQ29kZUJsb2NrSGVhZGVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMmQyZDJkO1xuICAgIGNvbG9yOiAjY2NjO1xuICAgIHBhZGRpbmc6IDVweCAxMHB4O1xuICAgIGZvbnQtc2l6ZTogMC44ZW07XG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICM0NDQ7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbn1cblxuLkNvZGVCbG9ja0J1dHRvbnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZ2FwOiA4cHg7XG59XG5cbi5Db3B5QnV0dG9uLFxuLkRvd25sb2FkQnV0dG9uLFxuLkNyZWF0ZUFnZW50QnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgY29sb3I6ICNhYWE7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZvbnQtc2l6ZTogaW5oZXJpdDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDVweDtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjJzO1xufVxuXG4uQ29weUJ1dHRvbjpob3Zlcixcbi5Eb3dubG9hZEJ1dHRvbjpob3Zlcixcbi5DcmVhdGVBZ2VudEJ1dHRvbjpob3ZlciB7XG4gICAgY29sb3I6ICNmZmY7XG59XG4iXX0= */";
7682
+ var styles$6 = {"CodeBlock":"CodeBlock-module_CodeBlock__6K33Z","CodeBlockHeader":"CodeBlock-module_CodeBlockHeader__tfOwl","CodeBlockButtons":"CodeBlock-module_CodeBlockButtons__rz1VO","CopyButton":"CodeBlock-module_CopyButton__M07tp","DownloadButton":"CodeBlock-module_DownloadButton__ZTrzQ","CreateAgentButton":"CodeBlock-module_CreateAgentButton__kUEnp"};
7683
+ styleInject(css_248z$7);
7684
+
7685
+ const LANGUAGE_EXTENSIONS = {
7686
+ python: 'py',
7687
+ javascript: 'js',
7688
+ typescript: 'ts',
7689
+ json: 'json',
7690
+ html: 'html',
7691
+ css: 'css',
7692
+ markdown: 'md',
7693
+ text: 'txt',
7694
+ xml: 'xml',
7695
+ sql: 'sql',
7696
+ sh: 'sh',
7697
+ bash: 'sh',
7698
+ zsh: 'sh',
7699
+ yaml: 'yaml',
7700
+ yml: 'yaml',
7701
+ book: 'book',
7702
+ };
7703
+ /**
7704
+ * Component to render a code block with syntax highlighting, copy, download, and create agent options.
7705
+ *
7706
+ * @private Internal utility of `<ChatMessage />` component
7707
+ */
7708
+ function CodeBlock({ code, language, className, onCreateAgent }) {
7709
+ const lines = react.useMemo(() => code.split('\n').length, [code]);
7710
+ // Note: 19px is approx line height for fontSize 14. +20 for padding.
7711
+ // We cap at 400px to avoid taking too much space, allowing scroll.
7712
+ const height = Math.min(Math.max(lines * 19, 19), 400);
7713
+ const [copied, setCopied] = react.useState(false);
7714
+ const handleDownload = () => {
7715
+ const lang = (language === null || language === void 0 ? void 0 : language.trim().toLowerCase()) || 'text';
7716
+ const extension = LANGUAGE_EXTENSIONS[lang] || lang;
7717
+ const filename = `file.${extension}`;
7718
+ downloadFile(code, filename, 'text/plain');
7719
+ };
7720
+ const handleCopy = async () => {
7721
+ try {
7722
+ await navigator.clipboard.writeText(code);
7723
+ setCopied(true);
7724
+ setTimeout(() => setCopied(false), 2000);
7725
+ }
7726
+ catch (error) {
7727
+ console.error('Failed to copy code to clipboard:', error);
7728
+ }
7729
+ };
7730
+ const header = language ? (jsxRuntime.jsxs("div", { className: styles$6.CodeBlockHeader, children: [jsxRuntime.jsx("span", { children: language }), jsxRuntime.jsxs("div", { className: styles$6.CodeBlockButtons, children: [jsxRuntime.jsx("button", { onClick: handleCopy, className: styles$6.CopyButton, title: "Copy to clipboard", children: copied ? 'Copied!' : 'Copy' }), jsxRuntime.jsx("button", { onClick: handleDownload, className: styles$6.DownloadButton, title: "Download code", children: "Download" }), (language === null || language === void 0 ? void 0 : language.trim().toLowerCase()) === 'book' && onCreateAgent && (jsxRuntime.jsx("button", { onClick: () => onCreateAgent(code), className: styles$6.CreateAgentButton, title: "Create agent from this book", children: "Create Agent" }))] })] })) : null;
7731
+ if ((language === null || language === void 0 ? void 0 : language.trim().toLowerCase()) === 'book') {
7732
+ return (jsxRuntime.jsxs("div", { className: classNames(styles$6.CodeBlock, className), children: [header, jsxRuntime.jsx(BookEditor, { value: code, isReadonly: true, height: lines * 25 /* <- [🧠] A bit more than 19px to accommodate BookEditor lines */ })] }));
7733
+ }
7734
+ return (jsxRuntime.jsxs("div", { className: classNames(styles$6.CodeBlock, className), children: [header, jsxRuntime.jsx(Editor__default["default"], { height: `${height}px`, language: language || 'plaintext', value: code, theme: "vs-dark", options: {
7735
+ readOnly: true,
7736
+ minimap: { enabled: false },
7737
+ scrollBeyondLastLine: false,
7738
+ lineNumbers: 'on',
7739
+ folding: false,
7740
+ glyphMargin: false,
7741
+ fontFamily: 'Consolas, "Courier New", monospace',
7742
+ fontSize: 14,
7743
+ lineHeight: 19,
7744
+ overviewRulerLanes: 0,
7745
+ hideCursorInOverviewRuler: true,
7746
+ renderLineHighlight: 'none',
7747
+ contextmenu: false,
7748
+ scrollbar: {
7749
+ vertical: 'auto',
7750
+ horizontal: 'auto',
7751
+ useShadows: false,
7752
+ },
7753
+ domReadOnly: true,
7754
+ wordWrap: 'off',
7755
+ } })] }));
7756
+ }
7757
+
7503
7758
  var css_248z$6 = ".MarkdownContent-module_MarkdownContent__2JuyX h1{font-size:2em}.MarkdownContent-module_MarkdownContent__2JuyX h2{font-size:1.75em}.MarkdownContent-module_MarkdownContent__2JuyX h3{font-size:1.5em}.MarkdownContent-module_MarkdownContent__2JuyX h4{font-size:1.25em}.MarkdownContent-module_MarkdownContent__2JuyX h5{font-size:1.1em}.MarkdownContent-module_MarkdownContent__2JuyX p{text-wrap:auto}.MarkdownContent-module_MarkdownContent__2JuyX ul{list-style:disc;margin-left:20px}.MarkdownContent-module_MarkdownContent__2JuyX ol{list-style:decimal;margin-left:20px}.MarkdownContent-module_MarkdownContent__2JuyX blockquote,.MarkdownContent-module_MarkdownContent__2JuyX img,.MarkdownContent-module_MarkdownContent__2JuyX pre,.MarkdownContent-module_MarkdownContent__2JuyX table{border-radius:8px;margin-bottom:10px;margin-top:10px}.MarkdownContent-module_MarkdownContent__2JuyX pre{background:#000;border:none;box-shadow:none;color:#fff;display:block;font-size:inherit;line-height:inherit;padding:1em}.MarkdownContent-module_MarkdownContent__2JuyX blockquote{background:#ffffffcc;border:none;box-shadow:none;color:#000;display:block;font-size:inherit;line-height:inherit;padding:1em}.MarkdownContent-module_MarkdownContent__2JuyX code{background:#cccccc55;border:none;box-shadow:none;color:inherit;display:inline-block;font-size:inherit;line-height:inherit;margin:0;padding:0}.MarkdownContent-module_MarkdownContent__2JuyX pre code{background-color:#000000cc;border-radius:8px}.MarkdownContent-module_MarkdownContent__2JuyX .MarkdownContent-module_chat-code-block__ZffFg{background:#181c23;border-color:#23272f;box-shadow:0 2px 8px rgba(0,0,0,.12);color:#f8fafc;font-family:Fira Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:14px;line-height:1.6;overflow-x:auto}.MarkdownContent-module_MarkdownContent__2JuyX .MarkdownContent-module_chat-code-block__ZffFg code{background:none!important;border:none!important;box-shadow:none!important;color:inherit!important;display:block;font-family:inherit!important;font-size:inherit!important;overflow-x:auto;padding:0!important;white-space:pre;word-break:break-word}.MarkdownContent-module_MarkdownContent__2JuyX table{background:#f8fafc;border-collapse:separate;border-spacing:0;box-shadow:0 2px 8px rgba(0,0,0,.08);color:#17223b;font-size:14px;margin:16px 0;width:100%}.MarkdownContent-module_MarkdownContent__2JuyX td,.MarkdownContent-module_MarkdownContent__2JuyX th{background:none;border-bottom:1px solid #d1dbe8;color:#17223b;padding:10px 16px;text-align:left}.MarkdownContent-module_MarkdownContent__2JuyX th{background:linear-gradient(90deg,#eaf3fa 80%,#d1e3f8);border-bottom:2px solid #b5c7de;color:#17223b;font-weight:700}.MarkdownContent-module_MarkdownContent__2JuyX tr:last-child td{border-bottom:none}.MarkdownContent-module_MarkdownContent__2JuyX tr:nth-child(2n) td{background:#eaf3fa}.MarkdownContent-module_MarkdownContent__2JuyX tr:hover td{background:#cbe0f7;transition:background .2s}.MarkdownContent-module_MarkdownContent__2JuyX table{border-radius:12px;overflow:hidden}.MarkdownContent-module_MarkdownContent__2JuyX td:first-child,.MarkdownContent-module_MarkdownContent__2JuyX th:first-child{border-top-left-radius:12px}.MarkdownContent-module_MarkdownContent__2JuyX td:last-child,.MarkdownContent-module_MarkdownContent__2JuyX th:last-child{border-top-right-radius:12px}.MarkdownContent-module_citation__11SMw{background:#e7f1ff;border-radius:4px;color:#007bff;cursor:default;display:inline-block;font-size:.7em;font-weight:700;margin:0 2px;padding:0 4px;user-select:none;vertical-align:super}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk1hcmtkb3duQ29udGVudC5tb2R1bGUuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGtEQUNJLGFBQ0osQ0FFQSxrREFDSSxnQkFDSixDQUVBLGtEQUNJLGVBQ0osQ0FFQSxrREFDSSxnQkFDSixDQUVBLGtEQUNJLGVBQ0osQ0FFQSxpREFDSSxjQUNKLENBRUEsa0RBQ0ksZUFBZ0IsQ0FDaEIsZ0JBQ0osQ0FFQSxrREFDSSxrQkFBbUIsQ0FDbkIsZ0JBQ0osQ0FFQSxxTkFNSSxpQkFBa0IsQ0FEbEIsa0JBQW1CLENBRG5CLGVBR0osQ0FFQSxtREFJSSxlQUFxQixDQUZyQixXQUFZLENBQ1osZUFBZ0IsQ0FJaEIsVUFBVyxDQU5YLGFBQWMsQ0FJZCxpQkFBa0IsQ0FDbEIsbUJBQW9CLENBRXBCLFdBQ0osQ0FFQSwwREFJSSxvQkFBcUIsQ0FGckIsV0FBWSxDQUNaLGVBQWdCLENBSWhCLFVBQVcsQ0FOWCxhQUFjLENBSWQsaUJBQWtCLENBQ2xCLG1CQUFvQixDQUVwQixXQUNKLENBRUEsb0RBTUksb0JBQXFCLENBRnJCLFdBQVksQ0FDWixlQUFnQixDQUloQixhQUFjLENBUmQsb0JBQXFCLENBTXJCLGlCQUFrQixDQUNsQixtQkFBb0IsQ0FOcEIsUUFBUyxDQUNULFNBT0osQ0FFQSx3REFDSSwwQkFBMkIsQ0FDM0IsaUJBQ0osQ0FFQSw4RkFDSSxrQkFBbUIsQ0FLbkIsb0JBQXFCLENBQ3JCLG9DQUF5QyxDQUx6QyxhQUFjLENBTWQsOERBQTJFLENBTDNFLGNBQWUsQ0FDZixlQUFnQixDQUNoQixlQUlKLENBQ0EsbUdBQ0kseUJBQTJCLENBSzNCLHFCQUF1QixDQUN2Qix5QkFBMkIsQ0FMM0IsdUJBQXlCLENBU3pCLGFBQWMsQ0FSZCw2QkFBK0IsQ0FDL0IsMkJBQTZCLENBTTdCLGVBQWdCLENBTGhCLG1CQUFxQixDQUdyQixlQUFnQixDQUNoQixxQkFHSixDQUNBLHFEQUtJLGtCQUFtQixDQUhuQix3QkFBeUIsQ0FDekIsZ0JBQWlCLENBS2pCLG9DQUF5QyxDQUV6QyxhQUFjLENBRGQsY0FBZSxDQUxmLGFBQWMsQ0FIZCxVQVVKLENBQ0Esb0dBTUksZUFBZ0IsQ0FIaEIsK0JBQWdDLENBRWhDLGFBQWMsQ0FIZCxpQkFBa0IsQ0FFbEIsZUFHSixDQUNBLGtEQUNJLHFEQUE2RCxDQUc3RCwrQkFBZ0MsQ0FEaEMsYUFBYyxDQURkLGVBR0osQ0FDQSxnRUFDSSxrQkFDSixDQUNBLG1FQUNJLGtCQUNKLENBQ0EsMkRBQ0ksa0JBQW1CLENBQ25CLHlCQUNKLENBQ0EscURBQ0ksa0JBQW1CLENBQ25CLGVBQ0osQ0FDQSw0SEFFSSwyQkFDSixDQUNBLDBIQUVJLDRCQUNKLENBRUEsd0NBTUksa0JBQW1CLENBRW5CLGlCQUFrQixDQUhsQixhQUFjLENBS2QsY0FBZSxDQVRmLG9CQUFxQixDQUVyQixjQUFnQixDQUNoQixlQUFpQixDQUtqQixZQUFhLENBRmIsYUFBYyxDQUlkLGdCQUFpQixDQVRqQixvQkFVSiIsImZpbGUiOiJNYXJrZG93bkNvbnRlbnQubW9kdWxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5NYXJrZG93bkNvbnRlbnQgaDEge1xuICAgIGZvbnQtc2l6ZTogMmVtO1xufVxuXG4uTWFya2Rvd25Db250ZW50IGgyIHtcbiAgICBmb250LXNpemU6IDEuNzVlbTtcbn1cblxuLk1hcmtkb3duQ29udGVudCBoMyB7XG4gICAgZm9udC1zaXplOiAxLjVlbTtcbn1cblxuLk1hcmtkb3duQ29udGVudCBoNCB7XG4gICAgZm9udC1zaXplOiAxLjI1ZW07XG59XG5cbi5NYXJrZG93bkNvbnRlbnQgaDUge1xuICAgIGZvbnQtc2l6ZTogMS4xZW07XG59XG5cbi5NYXJrZG93bkNvbnRlbnQgcCB7XG4gICAgdGV4dC13cmFwOiBhdXRvO1xufVxuXG4uTWFya2Rvd25Db250ZW50IHVsIHtcbiAgICBsaXN0LXN0eWxlOiBkaXNjO1xuICAgIG1hcmdpbi1sZWZ0OiAyMHB4O1xufVxuXG4uTWFya2Rvd25Db250ZW50IG9sIHtcbiAgICBsaXN0LXN0eWxlOiBkZWNpbWFsO1xuICAgIG1hcmdpbi1sZWZ0OiAyMHB4O1xufVxuXG4uTWFya2Rvd25Db250ZW50IGltZyxcbi5NYXJrZG93bkNvbnRlbnQgcHJlLFxuLk1hcmtkb3duQ29udGVudCBibG9ja3F1b3RlLFxuLk1hcmtkb3duQ29udGVudCB0YWJsZSB7XG4gICAgbWFyZ2luLXRvcDogMTBweDtcbiAgICBtYXJnaW4tYm90dG9tOiAxMHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDhweDtcbn1cblxuLk1hcmtkb3duQ29udGVudCBwcmUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIGJhY2tncm91bmQ6ICMwMDAwMDBmZjtcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgcGFkZGluZzogMWVtO1xufVxuXG4uTWFya2Rvd25Db250ZW50IGJsb2NrcXVvdGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICAgIGJhY2tncm91bmQ6ICNmZmZmZmZjYztcbiAgICBmb250LXNpemU6IGluaGVyaXQ7XG4gICAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gICAgY29sb3I6ICMwMDA7XG4gICAgcGFkZGluZzogMWVtO1xufVxuXG4uTWFya2Rvd25Db250ZW50IGNvZGUge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiAjY2NjY2NjNTU7XG4gICAgZm9udC1zaXplOiBpbmhlcml0O1xuICAgIGxpbmUtaGVpZ2h0OiBpbmhlcml0O1xuICAgIGNvbG9yOiBpbmhlcml0O1xufVxuXG4uTWFya2Rvd25Db250ZW50IHByZSBjb2RlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMDAwMDAwY2M7XG4gICAgYm9yZGVyLXJhZGl1czogOHB4O1xufVxuXG4uTWFya2Rvd25Db250ZW50IC5jaGF0LWNvZGUtYmxvY2sge1xuICAgIGJhY2tncm91bmQ6ICMxODFjMjM7XG4gICAgY29sb3I6ICNmOGZhZmM7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGxpbmUtaGVpZ2h0OiAxLjY7XG4gICAgb3ZlcmZsb3cteDogYXV0bztcbiAgICBib3JkZXItY29sb3I6ICMyMzI3MmY7XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4xMik7XG4gICAgZm9udC1mYW1pbHk6ICdGaXJhIE1vbm8nLCAnTWVubG8nLCAnQ29uc29sYXMnLCAnTGliZXJhdGlvbiBNb25vJywgbW9ub3NwYWNlO1xufVxuLk1hcmtkb3duQ29udGVudCAuY2hhdC1jb2RlLWJsb2NrIGNvZGUge1xuICAgIGJhY2tncm91bmQ6IG5vbmUgIWltcG9ydGFudDtcbiAgICBjb2xvcjogaW5oZXJpdCAhaW1wb3J0YW50O1xuICAgIGZvbnQtZmFtaWx5OiBpbmhlcml0ICFpbXBvcnRhbnQ7XG4gICAgZm9udC1zaXplOiBpbmhlcml0ICFpbXBvcnRhbnQ7XG4gICAgcGFkZGluZzogMCAhaW1wb3J0YW50O1xuICAgIGJvcmRlcjogbm9uZSAhaW1wb3J0YW50O1xuICAgIGJveC1zaGFkb3c6IG5vbmUgIWltcG9ydGFudDtcbiAgICB3aGl0ZS1zcGFjZTogcHJlO1xuICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG4gICAgb3ZlcmZsb3cteDogYXV0bztcbiAgICBkaXNwbGF5OiBibG9jaztcbn1cbi5NYXJrZG93bkNvbnRlbnQgdGFibGUge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7XG4gICAgYm9yZGVyLXNwYWNpbmc6IDA7XG4gICAgbWFyZ2luOiAxNnB4IDA7XG4gICAgYmFja2dyb3VuZDogI2Y4ZmFmYzsgLyogU3Ryb25nZXIgbGlnaHQgYmFja2dyb3VuZCBmb3IgY29udHJhc3QgKi9cbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm94LXNoYWRvdzogMCAycHggOHB4IHJnYmEoMCwgMCwgMCwgMC4wOCk7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIGNvbG9yOiAjMTcyMjNiOyAvKiBEYXJrIHRleHQgZm9yIGNvbnRyYXN0ICovXG59XG4uTWFya2Rvd25Db250ZW50IHRoLFxuLk1hcmtkb3duQ29udGVudCB0ZCB7XG4gICAgcGFkZGluZzogMTBweCAxNnB4O1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZDFkYmU4O1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgY29sb3I6ICMxNzIyM2I7IC8qIEVuc3VyZSBzdHJvbmcgdGV4dCBjb2xvciBmb3IgYWxsIGNlbGxzICovXG4gICAgYmFja2dyb3VuZDogbm9uZTtcbn1cbi5NYXJrZG93bkNvbnRlbnQgdGgge1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgI2VhZjNmYSA4MCUsICNkMWUzZjggMTAwJSk7XG4gICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICBjb2xvcjogIzE3MjIzYjsgLyogU3Ryb25nIGhlYWRlciB0ZXh0ICovXG4gICAgYm9yZGVyLWJvdHRvbTogMnB4IHNvbGlkICNiNWM3ZGU7XG59XG4uTWFya2Rvd25Db250ZW50IHRyOmxhc3QtY2hpbGQgdGQge1xuICAgIGJvcmRlci1ib3R0b206IG5vbmU7XG59XG4uTWFya2Rvd25Db250ZW50IHRyOm50aC1jaGlsZChldmVuKSB0ZCB7XG4gICAgYmFja2dyb3VuZDogI2VhZjNmYTtcbn1cbi5NYXJrZG93bkNvbnRlbnQgdHI6aG92ZXIgdGQge1xuICAgIGJhY2tncm91bmQ6ICNjYmUwZjc7XG4gICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjJzO1xufVxuLk1hcmtkb3duQ29udGVudCB0YWJsZSB7XG4gICAgYm9yZGVyLXJhZGl1czogMTJweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuLk1hcmtkb3duQ29udGVudCB0aDpmaXJzdC1jaGlsZCxcbi5NYXJrZG93bkNvbnRlbnQgdGQ6Zmlyc3QtY2hpbGQge1xuICAgIGJvcmRlci10b3AtbGVmdC1yYWRpdXM6IDEycHg7XG59XG4uTWFya2Rvd25Db250ZW50IHRoOmxhc3QtY2hpbGQsXG4uTWFya2Rvd25Db250ZW50IHRkOmxhc3QtY2hpbGQge1xuICAgIGJvcmRlci10b3AtcmlnaHQtcmFkaXVzOiAxMnB4O1xufVxuXG4uY2l0YXRpb24ge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICB2ZXJ0aWNhbC1hbGlnbjogc3VwZXI7XG4gICAgZm9udC1zaXplOiAwLjdlbTtcbiAgICBmb250LXdlaWdodDogYm9sZDtcbiAgICBjb2xvcjogIzAwN2JmZjtcbiAgICBiYWNrZ3JvdW5kOiAjZTdmMWZmO1xuICAgIHBhZGRpbmc6IDAgNHB4O1xuICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICBtYXJnaW46IDAgMnB4O1xuICAgIGN1cnNvcjogZGVmYXVsdDtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcbn1cblxuLyoqXG4gKiBUT0RPOiBb8J+MiV0gRFJZIE1hcmtkb3duIHByaW1pdGl2ZXMgc3R5bGluZ1xuICovXG4iXX0= */";
7504
7759
  var styles$5 = {"MarkdownContent":"MarkdownContent-module_MarkdownContent__2JuyX","chat-code-block":"MarkdownContent-module_chat-code-block__ZffFg","citation":"MarkdownContent-module_citation__11SMw"};
7505
7760
  styleInject(css_248z$6);
@@ -7602,32 +7857,8 @@
7602
7857
  }
7603
7858
  try {
7604
7859
  const processedMarkdown = renderMathInMarkdown(markdown);
7605
- let html = chatMarkdownConverter.makeHtml(processedMarkdown);
7606
- if (typeof window === 'undefined') {
7607
- html = html.replace(/<pre><code( class="language-([^"]+)")?>([\s\S]*?)<\/code><\/pre>/g, (match, _langClass, lang, code) => {
7608
- const decoded = code
7609
- .replace(/&/g, '&')
7610
- .replace(/</g, '<')
7611
- .replace(/>/g, '>')
7612
- .replace(/"/g, '"')
7613
- .replace(/&#39;/g, "'");
7614
- const highlighted = lang
7615
- ? hljs__default["default"].highlight(decoded, { language: lang }).value
7616
- : hljs__default["default"].highlightAuto(decoded).value;
7617
- return `<pre class="chat-code-block"><code class="hljs${lang ? ' language-' + lang : ''}">${highlighted}</code></pre>`;
7618
- });
7619
- }
7620
- else {
7621
- if (html.match(/<pre><code/)) {
7622
- const cssId = 'hljs-github-dark-css';
7623
- if (!window.document.getElementById(cssId)) {
7624
- const link = window.document.createElement('link');
7625
- link.id = cssId;
7626
- link.rel = 'stylesheet';
7627
- link.href = 'https://book-components.ptbk.io/cdn/highlightjs/github-dark.css';
7628
- window.document.head.appendChild(link);
7629
- }
7630
- }
7860
+ const html = chatMarkdownConverter.makeHtml(processedMarkdown);
7861
+ if (typeof window !== 'undefined') {
7631
7862
  if (html.match(/class="katex/)) {
7632
7863
  const katexCssId = 'katex-css';
7633
7864
  if (!window.document.getElementById(katexCssId)) {
@@ -7638,38 +7869,6 @@
7638
7869
  window.document.head.appendChild(link);
7639
7870
  }
7640
7871
  }
7641
- const parser = new window.DOMParser();
7642
- const doc = parser.parseFromString(html, 'text/html');
7643
- doc.querySelectorAll('pre > code').forEach((codeEl) => {
7644
- var _a;
7645
- const preEl = codeEl.parentElement;
7646
- if (!preEl)
7647
- return;
7648
- const lang = (_a = Array.from(codeEl.classList)
7649
- .find((cls) => cls.startsWith('language-'))) === null || _a === void 0 ? void 0 : _a.replace('language-', '');
7650
- const code = codeEl.innerHTML;
7651
- let highlighted = '';
7652
- try {
7653
- const decoded = code
7654
- .replace(/&/g, '&')
7655
- .replace(/</g, '<')
7656
- .replace(/>/g, '>')
7657
- .replace(/"/g, '"')
7658
- .replace(/&#39;/g, "'");
7659
- highlighted = lang
7660
- ? hljs__default["default"].highlight(decoded, { language: lang }).value
7661
- : hljs__default["default"].highlightAuto(decoded).value;
7662
- }
7663
- catch (_b) {
7664
- highlighted = code;
7665
- }
7666
- codeEl.innerHTML = highlighted;
7667
- codeEl.classList.add('hljs');
7668
- if (lang)
7669
- codeEl.classList.add(`language-${lang}`);
7670
- preEl.classList.add('chat-code-block');
7671
- });
7672
- html = doc.body.innerHTML;
7673
7872
  }
7674
7873
  const sanitizedHtml = html
7675
7874
  .replace(/<\s*(script|style|iframe|object|embed)[^>]*>[\s\S]*?<\s*\/\s*\1\s*>/gi, '')
@@ -7699,9 +7898,50 @@
7699
7898
  * @public exported from `@promptbook/components`
7700
7899
  */
7701
7900
  function MarkdownContent(props) {
7702
- const { content, className } = props;
7901
+ const { content, className, onCreateAgent } = props;
7703
7902
  const htmlContent = react.useMemo(() => renderMarkdown(content), [content]);
7704
- return (jsxRuntime.jsx("div", { className: classNames(styles$5.MarkdownContent, className), dangerouslySetInnerHTML: {
7903
+ const containerRef = react.useRef(null);
7904
+ const rootsRef = react.useRef([]);
7905
+ react.useEffect(() => {
7906
+ // Cleanup previous roots
7907
+ rootsRef.current.forEach((root) => root.unmount());
7908
+ rootsRef.current = [];
7909
+ if (!containerRef.current) {
7910
+ return;
7911
+ }
7912
+ const preElements = containerRef.current.querySelectorAll('pre');
7913
+ preElements.forEach((pre) => {
7914
+ // Check if it is a code block (has code element)
7915
+ const codeElement = pre.querySelector('code');
7916
+ if (!codeElement) {
7917
+ return;
7918
+ }
7919
+ // Get language and code
7920
+ const className = codeElement.className; // e.g. language-python
7921
+ const match = className.match(/language-([^\s]+)/);
7922
+ const language = match ? match[1] : undefined;
7923
+ const code = codeElement.textContent || '';
7924
+ // Clear the pre element content
7925
+ pre.innerHTML = '';
7926
+ pre.className = ''; // remove existing classes if any
7927
+ pre.style.background = 'none'; // reset styles
7928
+ pre.style.padding = '0';
7929
+ pre.style.margin = '0';
7930
+ pre.style.overflow = 'visible';
7931
+ // Create a container for the CodeBlock
7932
+ const mountPoint = document.createElement('div');
7933
+ pre.appendChild(mountPoint);
7934
+ // Render CodeBlock
7935
+ const root = client.createRoot(mountPoint);
7936
+ root.render(jsxRuntime.jsx(CodeBlock, { code: code, language: language, onCreateAgent: onCreateAgent }));
7937
+ rootsRef.current.push(root);
7938
+ });
7939
+ return () => {
7940
+ rootsRef.current.forEach((root) => root.unmount());
7941
+ rootsRef.current = [];
7942
+ };
7943
+ }, [htmlContent, onCreateAgent]);
7944
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: classNames(styles$5.MarkdownContent, className), dangerouslySetInnerHTML: {
7705
7945
  __html: htmlContent,
7706
7946
  } }));
7707
7947
  }
@@ -7918,6 +8158,16 @@
7918
8158
  }, children: [icon, jsxRuntime.jsx("span", { children: name })] }, name))) }))] }));
7919
8159
  }
7920
8160
 
8161
+ const MenuHoistingContext = react.createContext(null);
8162
+ /**
8163
+ * Hook to use the menu hoisting system
8164
+ *
8165
+ * @private mechanism inside Promptbook
8166
+ */
8167
+ function useMenuHoisting() {
8168
+ return react.useContext(MenuHoistingContext);
8169
+ }
8170
+
7921
8171
  /**
7922
8172
  *
7923
8173
  * @private Internal component used by `BookEditor`
@@ -7925,50 +8175,83 @@
7925
8175
  function BookEditorActionbar(props) {
7926
8176
  const { value, isDownloadButtonShown, isUploadButtonShown, isCameraButtonShown, isAboutButtonShown, isFullscreenButtonShown, onFullscreenClick, onUploadDocument, onTakePhoto, isFullscreen, } = props;
7927
8177
  const [isAboutModalOpen, setIsAboutModalOpen] = react.useState(false);
7928
- const handleDownload = () => {
7929
- const book = validateBook(value || DEFAULT_BOOK);
8178
+ const menuHoisting = useMenuHoisting();
8179
+ // Note: [1] We use ref to avoid re-creating the handleDownload function (and thus the actions array) on every value change
8180
+ const valueRef = react.useRef(value);
8181
+ react.useEffect(() => {
8182
+ valueRef.current = value;
8183
+ }, [value]);
8184
+ const handleDownload = react.useCallback(() => {
8185
+ const book = validateBook(valueRef.current || DEFAULT_BOOK);
7930
8186
  /* not await */ $induceBookDownload(book);
7931
- };
7932
- const actions = [];
7933
- if (isUploadButtonShown && onUploadDocument) {
7934
- actions.push({
7935
- icon: jsxRuntime.jsx(AttachmentIcon, {}),
7936
- name: 'Upload document',
7937
- onClick: onUploadDocument,
7938
- });
7939
- }
7940
- if (isCameraButtonShown && onTakePhoto) {
7941
- actions.push({
7942
- icon: jsxRuntime.jsx(CameraIcon, {}),
7943
- name: 'Take photo',
7944
- onClick: onTakePhoto,
7945
- });
7946
- }
7947
- if (isDownloadButtonShown) {
7948
- actions.push({
7949
- icon: jsxRuntime.jsx(DownloadIcon, {}),
7950
- name: 'Download',
7951
- onClick: handleDownload,
7952
- });
7953
- }
7954
- if (isAboutButtonShown) {
7955
- actions.push({
7956
- icon: jsxRuntime.jsx(AboutIcon, {}),
7957
- name: 'About',
7958
- onClick: () => setIsAboutModalOpen(true),
7959
- });
7960
- }
7961
- if (isFullscreenButtonShown && onFullscreenClick) {
7962
- actions.push({
7963
- icon: jsxRuntime.jsx(FullscreenIcon, {}),
7964
- name: 'Fullscreen',
7965
- onClick: onFullscreenClick,
7966
- });
7967
- }
8187
+ }, []);
8188
+ const actions = react.useMemo(() => {
8189
+ const _actions = [];
8190
+ if (isUploadButtonShown && onUploadDocument) {
8191
+ _actions.push({
8192
+ icon: jsxRuntime.jsx(AttachmentIcon, {}),
8193
+ name: 'Upload document',
8194
+ onClick: onUploadDocument,
8195
+ });
8196
+ }
8197
+ if (isCameraButtonShown && onTakePhoto) {
8198
+ _actions.push({
8199
+ icon: jsxRuntime.jsx(CameraIcon, {}),
8200
+ name: 'Take photo',
8201
+ onClick: onTakePhoto,
8202
+ });
8203
+ }
8204
+ if (isDownloadButtonShown) {
8205
+ _actions.push({
8206
+ icon: jsxRuntime.jsx(DownloadIcon, {}),
8207
+ name: 'Download',
8208
+ onClick: handleDownload,
8209
+ });
8210
+ }
8211
+ if (isAboutButtonShown) {
8212
+ _actions.push({
8213
+ icon: jsxRuntime.jsx(AboutIcon, {}),
8214
+ name: 'About',
8215
+ onClick: () => setIsAboutModalOpen(true),
8216
+ });
8217
+ }
8218
+ if (isFullscreenButtonShown && onFullscreenClick) {
8219
+ _actions.push({
8220
+ icon: jsxRuntime.jsx(FullscreenIcon, {}),
8221
+ name: 'Fullscreen',
8222
+ onClick: onFullscreenClick,
8223
+ });
8224
+ }
8225
+ return _actions;
8226
+ }, [
8227
+ isUploadButtonShown,
8228
+ onUploadDocument,
8229
+ isCameraButtonShown,
8230
+ onTakePhoto,
8231
+ isDownloadButtonShown,
8232
+ handleDownload,
8233
+ isAboutButtonShown,
8234
+ isFullscreenButtonShown,
8235
+ onFullscreenClick,
8236
+ ]);
8237
+ react.useEffect(() => {
8238
+ if (!menuHoisting || isFullscreen) {
8239
+ return;
8240
+ }
8241
+ menuHoisting.setMenu(actions);
8242
+ return () => {
8243
+ menuHoisting.setMenu([]);
8244
+ };
8245
+ }, [menuHoisting, actions, isFullscreen]);
7968
8246
  if (isFullscreen) {
7969
- return (jsxRuntime.jsx("div", { className: styles$6.bookEditorActionbar, children: jsxRuntime.jsx("button", { className: styles$6.button, onClick: onFullscreenClick, children: jsxRuntime.jsx(ExitFullscreenIcon, {}) }) }));
8247
+ return (jsxRuntime.jsx("div", { className: styles$7.bookEditorActionbar, children: jsxRuntime.jsx("button", { className: styles$7.button, onClick: onFullscreenClick, children: jsxRuntime.jsx(ExitFullscreenIcon, {}) }) }));
7970
8248
  }
7971
- return (jsxRuntime.jsxs("div", { className: styles$6.bookEditorActionbar, children: [actions.length >= 2 ? (jsxRuntime.jsx(Dropdown, { actions: actions })) : (actions.map(({ icon, name, onClick }) => (jsxRuntime.jsx("button", { className: styles$6.button, onClick: onClick, children: icon }, name)))), isAboutModalOpen && (jsxRuntime.jsx(Modal, { onClose: () => {
8249
+ if (menuHoisting && !isFullscreen) {
8250
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: isAboutModalOpen && (jsxRuntime.jsx(Modal, { onClose: () => {
8251
+ setIsAboutModalOpen(false);
8252
+ }, children: jsxRuntime.jsx(AboutPromptbookInformation, {}) })) }));
8253
+ }
8254
+ return (jsxRuntime.jsxs("div", { className: styles$7.bookEditorActionbar, children: [actions.length >= 2 ? (jsxRuntime.jsx(Dropdown, { actions: actions })) : (actions.map(({ icon, name, onClick }) => (jsxRuntime.jsx("button", { className: styles$7.button, onClick: onClick, children: icon }, name)))), isAboutModalOpen && (jsxRuntime.jsx(Modal, { onClose: () => {
7972
8255
  setIsAboutModalOpen(false);
7973
8256
  }, children: jsxRuntime.jsx(AboutPromptbookInformation, {}) }))] }));
7974
8257
  }
@@ -8080,6 +8363,7 @@
8080
8363
  const parameterRegex = /@([a-zA-Z0-9_á-žÁ-Žč-řČ-Řš-žŠ-Žа-яА-ЯёЁ]+)/;
8081
8364
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8082
8365
  const bookRules = [
8366
+ [/^---[-]*$/, ''],
8083
8367
  [parameterRegex, 'parameter'],
8084
8368
  [/\{[^}]+\}/, 'parameter'],
8085
8369
  [commitmentRegex, 'commitment'],
@@ -8088,7 +8372,12 @@
8088
8372
  const tokenProvider = monaco.languages.setMonarchTokensProvider(BOOK_LANGUAGE_ID, {
8089
8373
  ignoreCase: true,
8090
8374
  tokenizer: {
8091
- root: [[/^.*$/, 'title', '@body']],
8375
+ root: [
8376
+ [/^\s*$/, 'empty'],
8377
+ [/^-*$/, 'line'],
8378
+ [/^.*$/, 'title', '@body'],
8379
+ [commitmentRegex, 'commitment'],
8380
+ ],
8092
8381
  body: bookRules,
8093
8382
  },
8094
8383
  });
@@ -8306,7 +8595,7 @@
8306
8595
  event.preventDefault();
8307
8596
  setIsDragOver(false);
8308
8597
  }, []);
8309
- return (jsxRuntime.jsxs("div", { className: classNames(styles$6.bookEditorContainer, instanceClass), onDrop: handleDrop, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, children: [(isUploadButtonShown ||
8598
+ return (jsxRuntime.jsxs("div", { className: classNames(styles$7.bookEditorContainer, instanceClass), onDrop: handleDrop, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, children: [(isUploadButtonShown ||
8310
8599
  isCameraButtonShown ||
8311
8600
  isDownloadButtonShown ||
8312
8601
  isAboutButtonShown ||
@@ -8319,7 +8608,7 @@
8319
8608
  onFullscreenClick,
8320
8609
  onUploadDocument: handleUploadDocument,
8321
8610
  onTakePhoto: handleTakePhoto,
8322
- isFullscreen })), jsxRuntime.jsx("input", { type: "file", ref: fileUploadInputRef, style: { display: 'none' }, onChange: handleFileInputChange, multiple: true }), jsxRuntime.jsx("input", { type: "file", ref: cameraInputRef, style: { display: 'none' }, accept: "image/*", capture: "environment", onChange: handleFileInputChange }), isDragOver && jsxRuntime.jsx("div", { className: styles$6.dropOverlay, children: "Drop files to upload" }), jsxRuntime.jsxs("div", { style: {
8611
+ isFullscreen })), jsxRuntime.jsx("input", { type: "file", ref: fileUploadInputRef, style: { display: 'none' }, onChange: handleFileInputChange, multiple: true }), jsxRuntime.jsx("input", { type: "file", ref: cameraInputRef, style: { display: 'none' }, accept: "image/*", capture: "environment", onChange: handleFileInputChange }), isDragOver && jsxRuntime.jsx("div", { className: styles$7.dropOverlay, children: "Drop files to upload" }), jsxRuntime.jsxs("div", { style: {
8323
8612
  position: 'relative',
8324
8613
  flex: 1,
8325
8614
  height: '100%',
@@ -8384,7 +8673,7 @@
8384
8673
  arrowSize: 0,
8385
8674
  useShadows: false,
8386
8675
  },
8387
- }, loading: jsxRuntime.jsx("div", { className: styles$6.loading, children: "\uD83D\uDCD6" }) })] })] }));
8676
+ }, loading: jsxRuntime.jsx("div", { className: styles$7.loading, children: "\uD83D\uDCD6" }) })] })] }));
8388
8677
  }
8389
8678
 
8390
8679
  /**
@@ -8406,7 +8695,7 @@
8406
8695
  const handleFullscreenToggle = () => {
8407
8696
  setIsFullscreen(!isFullscreen);
8408
8697
  };
8409
- const editorContent = (jsxRuntime.jsx("div", { "data-book-component": "BookEditor", className: classNames(styles$6.BookEditor, isVerbose && styles$6.isVerbose, styles$6.bookEditorWrapper, isBorderRadiusDisabled && styles$6.isBorderRadiusDisabled, isFullscreen && styles$6.fullscreen, className), style: isFullscreen
8698
+ const editorContent = (jsxRuntime.jsx("div", { "data-book-component": "BookEditor", className: classNames(styles$7.BookEditor, isVerbose && styles$7.isVerbose, styles$7.bookEditorWrapper, isBorderRadiusDisabled && styles$7.isBorderRadiusDisabled, isFullscreen && styles$7.fullscreen, className), style: isFullscreen
8410
8699
  ? style
8411
8700
  : {
8412
8701
  ...(style || {}),
@@ -9014,15 +9303,15 @@
9014
9303
  ASSISTANT: '#ffb300',
9015
9304
  SYSTEM: '#888',
9016
9305
  };
9017
- const bgColor = participantColors[String(message.from)] || '#2b7cff';
9306
+ const bgColor = participantColors[String(message.sender)] || '#2b7cff';
9018
9307
  const textColor = getTextColor(bgColor);
9019
9308
  return spaceTrim__default["default"](`
9020
9309
  <div class="chat-message">
9021
9310
  <div class="avatar" style="background:${bgColor};color:${getTextColor(bgColor)};">
9022
- ${String(message.from)[0] || '?'}
9311
+ ${String(message.sender)[0] || '?'}
9023
9312
  </div>
9024
9313
  <div class="bubble" style="background:${bgColor};color:${textColor};">
9025
- <span class="from-label">${String(message.from)}:</span>
9314
+ <span class="from-label">${String(message.sender)}:</span>
9026
9315
  ${message.content}
9027
9316
  </div>
9028
9317
  </div>
@@ -9068,7 +9357,7 @@
9068
9357
  getContent: ({ messages }) => spaceTrim$1.spaceTrim(`
9069
9358
  ${messages
9070
9359
  .map((message) => spaceTrim$1.spaceTrim(`
9071
- **${message.from}:**
9360
+ **${message.sender}:**
9072
9361
 
9073
9362
  > ${message.content.replace(/\n/g, '\n> ')}
9074
9363
  `))
@@ -9258,7 +9547,7 @@
9258
9547
  *
9259
9548
  * @private internal subcomponent of `<Chat>` component
9260
9549
  */
9261
- const ChatMessageItem = react.memo(({ message, participant, participants, isLastMessage, onMessage, setExpandedMessageId, isExpanded, currentRating, handleRating, mode, isCopyButtonEnabled, isFeedbackEnabled, onCopy, }) => {
9550
+ const ChatMessageItem = react.memo(({ message, participant, participants, isLastMessage, onMessage, setExpandedMessageId, isExpanded, currentRating, handleRating, mode, isCopyButtonEnabled, isFeedbackEnabled, onCopy, onCreateAgent, }) => {
9262
9551
  const avatarSrc = (participant === null || participant === void 0 ? void 0 : participant.avatarSrc) || '';
9263
9552
  const [isAvatarTooltipVisible, setIsAvatarTooltipVisible] = react.useState(false);
9264
9553
  const [avatarTooltipPosition, setAvatarTooltipPosition] = react.useState(null);
@@ -9350,7 +9639,7 @@
9350
9639
  console.info('participant avatarSrc', avatarSrc);
9351
9640
  console.info('participant color', { color, colorOfText });
9352
9641
  console.groupEnd();
9353
- }, children: [avatarSrc && (jsxRuntime.jsxs("div", { ref: avatarRef, className: chatStyles.avatar, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onClick: showTooltip, children: [jsxRuntime.jsx("img", { width: AVATAR_SIZE, src: avatarSrc, alt: `Avatar of ${message.from.toString().toLocaleLowerCase()}`, style: {
9642
+ }, children: [avatarSrc && (jsxRuntime.jsxs("div", { ref: avatarRef, className: chatStyles.avatar, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onClick: showTooltip, children: [jsxRuntime.jsx("img", { width: AVATAR_SIZE, src: avatarSrc, alt: `Avatar of ${message.sender.toString().toLocaleLowerCase()}`, style: {
9354
9643
  '--avatar-bg-color': color.toHex(),
9355
9644
  width: AVATAR_SIZE,
9356
9645
  } }), isAvatarTooltipVisible && (participant === null || participant === void 0 ? void 0 : participant.agentSource) && avatarTooltipPosition && (jsxRuntime.jsx(AvatarProfileTooltip, { ref: tooltipRef, agentSource: participant.agentSource, position: avatarTooltipPosition }))] })), jsxRuntime.jsxs("div", { className: chatStyles.messageText, style: {
@@ -9401,7 +9690,7 @@
9401
9690
  ? ' ' + chatStyles.copiedTooltipLeft
9402
9691
  : tooltipAlign === 'right'
9403
9692
  ? ' ' + chatStyles.copiedTooltipRight
9404
- : ''), children: "Copied!" }))] }) })), message.isVoiceCall && (jsxRuntime.jsx("div", { className: chatStyles.voiceCallIndicator, children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntime.jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }) })), message.content === LOADING_INTERACTIVE_IMAGE ? (jsxRuntime.jsx(jsxRuntime.Fragment, {})) : (jsxRuntime.jsx("div", { ref: contentWithoutButtonsRef, children: jsxRuntime.jsx(MarkdownContent, { content: contentWithoutButtons }) })), !message.isComplete && jsxRuntime.jsx("span", { className: chatStyles.NonCompleteMessageFiller, children: '_'.repeat(70) }), shouldShowButtons && (jsxRuntime.jsx("div", { className: chatStyles.messageButtons, children: buttons.map((button, buttonIndex) => (jsxRuntime.jsx("button", { className: chatStyles.messageButton, onClick: (event) => {
9693
+ : ''), children: "Copied!" }))] }) })), message.isVoiceCall && (jsxRuntime.jsx("div", { className: chatStyles.voiceCallIndicator, children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntime.jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }) })), message.content === LOADING_INTERACTIVE_IMAGE ? (jsxRuntime.jsx(jsxRuntime.Fragment, {})) : (jsxRuntime.jsx("div", { ref: contentWithoutButtonsRef, children: jsxRuntime.jsx(MarkdownContent, { content: contentWithoutButtons, onCreateAgent: onCreateAgent }) })), !message.isComplete && jsxRuntime.jsx("span", { className: chatStyles.NonCompleteMessageFiller, children: '_'.repeat(70) }), shouldShowButtons && (jsxRuntime.jsx("div", { className: chatStyles.messageButtons, children: buttons.map((button, buttonIndex) => (jsxRuntime.jsx("button", { className: chatStyles.messageButton, onClick: (event) => {
9405
9694
  event.stopPropagation();
9406
9695
  if (onMessage) {
9407
9696
  onMessage(button.message);
@@ -9484,7 +9773,7 @@
9484
9773
  // isExperimental = false,
9485
9774
  // TODO: [😅]> isSaveButtonEnabled = false,
9486
9775
  // exportHeaderMarkdown,
9487
- participants = [], extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, } = props;
9776
+ participants = [], extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, } = props;
9488
9777
  const buttonColor = react.useMemo(() => Color.from(buttonColorRaw || '#0066cc'), [buttonColorRaw]);
9489
9778
  // Use the auto-scroll hook
9490
9779
  const { isAutoScrolling, chatMessagesRef, handleScroll, handleMessagesChange, scrollToBottom, isMobile: isMobileFromHook, } = useChatAutoScroll();
@@ -9699,7 +9988,7 @@
9699
9988
  }
9700
9989
  }, [ratingModalOpen, isMobile]);
9701
9990
  // Determine alignment for actions (Reset button) based on the first message
9702
- const firstMessageFromUser = ((_a = messages[0]) === null || _a === void 0 ? void 0 : _a.from) === 'USER';
9991
+ const firstMessageFromUser = ((_a = messages[0]) === null || _a === void 0 ? void 0 : _a.sender) === 'USER';
9703
9992
  const actionsAlignmentClass = firstMessageFromUser
9704
9993
  ? chatStyles.actions + ' ' + chatStyles.left
9705
9994
  : chatStyles.actions + ' ' + chatStyles.right;
@@ -9776,11 +10065,11 @@
9776
10065
  }
9777
10066
  return true;
9778
10067
  })() && chatStyles.hasActionsAndFirstMessageIsLong), ref: chatMessagesRef, onScroll: handleScroll, children: [postprocessedMessages.map((message, i) => {
9779
- const participant = participants.find((participant) => participant.name === message.from);
10068
+ const participant = participants.find((participant) => participant.name === message.sender);
9780
10069
  const isLastMessage = i === postprocessedMessages.length - 1;
9781
10070
  const isExpanded = expandedMessageId === message.id;
9782
10071
  const currentRating = messageRatings.get(message.id || message.content /* <-[💃] */) || 0;
9783
- return (jsxRuntime.jsx(ChatMessageItem, { message: message, participant: participant, participants: participants, isLastMessage: isLastMessage, onMessage: onMessage, setExpandedMessageId: setExpandedMessageId, isExpanded: isExpanded, currentRating: currentRating, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, onCopy: handleCopy }, message.id));
10072
+ return (jsxRuntime.jsx(ChatMessageItem, { message: message, participant: participant, participants: participants, isLastMessage: isLastMessage, onMessage: onMessage, setExpandedMessageId: setExpandedMessageId, isExpanded: isExpanded, currentRating: currentRating, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, onCopy: handleCopy, onCreateAgent: onCreateAgent }, message.id));
9784
10073
  }), jsxRuntime.jsx("div", {
9785
10074
  // Note: Extra space at bottom for input area
9786
10075
  style: { height: 100 } })] }), onMessage && (jsxRuntime.jsxs("div", { className: classNames(chatStyles.chatInput, useChatCssClassName('chatInput'), isDragOver && chatStyles.dragOver), ...(onFileUpload
@@ -9868,13 +10157,13 @@
9868
10157
  const idx = postprocessedMessages.findIndex((m) => m.id === selectedMessage.id);
9869
10158
  if (idx > 0) {
9870
10159
  const prev = postprocessedMessages[idx - 1];
9871
- if (prev.from === 'USER') {
10160
+ if (prev.sender === 'USER') {
9872
10161
  return prev.content;
9873
10162
  }
9874
10163
  }
9875
10164
  // fallback: find last USER message before selectedMessage
9876
10165
  for (let i = messages.findIndex((m) => m.id === selectedMessage.id) - 1; i >= 0; i--) {
9877
- if (messages[i].from === 'USER') {
10166
+ if (messages[i].sender === 'USER') {
9878
10167
  return messages[i].content;
9879
10168
  }
9880
10169
  }
@@ -9901,7 +10190,9 @@
9901
10190
  try {
9902
10191
  const serializableMessages = messages.map((message) => ({
9903
10192
  ...message,
9904
- date: (message.date || new Date()).toISOString(),
10193
+ createdAt: (typeof message.createdAt === 'string'
10194
+ ? new Date(message.createdAt)
10195
+ : message.createdAt || new Date()).toISOString(),
9905
10196
  }));
9906
10197
  const storageKey = this.STORAGE_PREFIX + persistenceKey;
9907
10198
  localStorage.setItem(storageKey, JSON.stringify(serializableMessages));
@@ -9924,7 +10215,7 @@
9924
10215
  // Convert date strings back to Date objects
9925
10216
  return serializableMessages.map((message) => ({
9926
10217
  ...message,
9927
- date: new Date(message.date),
10218
+ createdAt: new Date(message.createdAt),
9928
10219
  }));
9929
10220
  }
9930
10221
  catch (error) {
@@ -9977,7 +10268,7 @@
9977
10268
  const { llmTools, persistenceKey, onChange, onReset, initialMessages, sendMessage, userParticipantName = 'USER', llmParticipantName = 'ASSISTANT', autoExecuteMessage, buttonColor, ...restProps } = props;
9978
10269
  // Internal state management
9979
10270
  // DRY: Single factory for seeding initial messages (used on mount and after reset)
9980
- const buildInitialMessages = react.useCallback(() => (initialMessages ? [...initialMessages] : []), [initialMessages]);
10271
+ const buildInitialMessages = react.useCallback(() => initialMessages ? ([...initialMessages]) : ([]), [initialMessages]);
9981
10272
  const [messages, setMessages] = react.useState(() => buildInitialMessages());
9982
10273
  const [tasksProgress, setTasksProgress] = react.useState([]);
9983
10274
  const [isVoiceCalling, setIsVoiceCalling] = react.useState(false);
@@ -10070,17 +10361,19 @@
10070
10361
  setTasksProgress([{ id: taskId, name: 'Playing response...', progress: 100 }]);
10071
10362
  const now = Date.now();
10072
10363
  const userMessage = {
10364
+ // channel: 'PROMPTBOOK_CHAT',
10073
10365
  id: `user_${now}`,
10074
- date: new Date(),
10075
- from: userParticipantName,
10366
+ createdAt: new Date(),
10367
+ sender: userParticipantName,
10076
10368
  content: (result.userMessage || '(Voice message)'),
10077
10369
  isComplete: true,
10078
10370
  isVoiceCall: true,
10079
10371
  };
10080
10372
  const agentMessage = {
10373
+ // channel: 'PROMPTBOOK_CHAT',
10081
10374
  id: `agent_${now}`,
10082
- date: new Date(),
10083
- from: llmParticipantName,
10375
+ createdAt: new Date(),
10376
+ sender: llmParticipantName,
10084
10377
  content: (result.agentMessage || result.text),
10085
10378
  isComplete: true,
10086
10379
  isVoiceCall: true,
@@ -10177,9 +10470,10 @@
10177
10470
  hasUserInteractedRef.current = true;
10178
10471
  // Add user message
10179
10472
  const userMessage = {
10473
+ // channel: 'PROMPTBOOK_CHAT',
10180
10474
  id: `user_${Date.now()}`,
10181
- date: new Date(),
10182
- from: userParticipantName,
10475
+ createdAt: new Date(),
10476
+ sender: userParticipantName,
10183
10477
  content: messageContent,
10184
10478
  isComplete: true,
10185
10479
  };
@@ -10191,9 +10485,10 @@
10191
10485
  }
10192
10486
  // Add loading message for assistant
10193
10487
  const loadingMessage = {
10488
+ // channel: 'PROMPTBOOK_CHAT',
10194
10489
  id: `assistant_${Date.now()}`,
10195
- date: new Date(),
10196
- from: llmParticipantName,
10490
+ createdAt: new Date(),
10491
+ sender: llmParticipantName,
10197
10492
  content: 'Thinking...',
10198
10493
  isComplete: false,
10199
10494
  };
@@ -10224,9 +10519,10 @@
10224
10519
  if (llmTools.callChatModelStream) {
10225
10520
  result = await llmTools.callChatModelStream(prompt, (chunk) => {
10226
10521
  const assistantMessage = {
10522
+ // channel: 'PROMPTBOOK_CHAT',
10227
10523
  id: loadingMessage.id,
10228
- date: new Date(),
10229
- from: llmParticipantName,
10524
+ createdAt: new Date(),
10525
+ sender: llmParticipantName,
10230
10526
  content: chunk.content,
10231
10527
  isComplete: false,
10232
10528
  };
@@ -10247,9 +10543,10 @@
10247
10543
  setTasksProgress([{ id: taskId, name: 'Response generated', progress: 100 }]);
10248
10544
  // Replace loading message with actual response
10249
10545
  const assistantMessage = {
10546
+ // channel: 'PROMPTBOOK_CHAT',
10250
10547
  id: loadingMessage.id,
10251
- date: new Date(),
10252
- from: llmParticipantName,
10548
+ createdAt: new Date(),
10549
+ sender: llmParticipantName,
10253
10550
  content: result.content,
10254
10551
  isComplete: true,
10255
10552
  };
@@ -10268,9 +10565,10 @@
10268
10565
  console.error('Error calling LLM:', error);
10269
10566
  // Replace loading message with error message
10270
10567
  const errorMessage = {
10568
+ // channel: 'PROMPTBOOK_CHAT',
10271
10569
  id: loadingMessage.id,
10272
- date: new Date(),
10273
- from: llmParticipantName,
10570
+ createdAt: new Date(),
10571
+ sender: llmParticipantName,
10274
10572
  content: `Sorry, I encountered an error: ${error instanceof Error ? error.message : 'Unknown error'}`,
10275
10573
  isComplete: true,
10276
10574
  };
@@ -10337,7 +10635,8 @@
10337
10635
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(LlmChat, { title: title || `Chat with ${agent.meta.fullname || agent.agentName || 'Agent'}`, persistenceKey: persistenceKey || `agent-chat-${agent.agentName}`, userParticipantName: "USER", llmParticipantName: "AGENT" // <- TODO: [🧠] Maybe dynamic agent id
10338
10636
  , initialMessages: [
10339
10637
  {
10340
- from: 'AGENT',
10638
+ // channel: 'PROMPTBOOK_CHAT',
10639
+ sender: 'AGENT',
10341
10640
  content: agent.initialMessage ||
10342
10641
  spaceTrim__default["default"](`
10343
10642
 
@@ -10615,7 +10914,7 @@
10615
10914
  if (delays.longPauseChance &&
10616
10915
  Math.random() < delays.longPauseChance &&
10617
10916
  i > 0 &&
10618
- originalMessages[i].from !== originalMessages[i - 1].from) {
10917
+ originalMessages[i].sender !== originalMessages[i - 1].sender) {
10619
10918
  await waitasecond.forTime(getDelay(delays.longPauseDuration, 2000));
10620
10919
  didLongPause = true;
10621
10920
  if (isCancelled)
@@ -10636,9 +10935,10 @@
10636
10935
  }
10637
10936
  // Show incomplete message first (for typing effect)
10638
10937
  const incompleteMessage = {
10938
+ // channel: 'PROMPTBOOK_CHAT',
10639
10939
  id: currentMessage.id,
10640
- date: currentMessage.date,
10641
- from: currentMessage.from,
10940
+ createdAt: currentMessage.createdAt,
10941
+ sender: currentMessage.sender,
10642
10942
  content: '',
10643
10943
  isComplete: false,
10644
10944
  expectedAnswer: currentMessage.expectedAnswer,
@@ -10656,9 +10956,10 @@
10656
10956
  currentContent += (wordIndex > 0 ? ' ' : '') + word;
10657
10957
  // Update the message with current content
10658
10958
  const updatingMessage = {
10959
+ // channel: 'PROMPTBOOK_CHAT',
10659
10960
  id: currentMessage.id,
10660
- date: currentMessage.date,
10661
- from: currentMessage.from,
10961
+ createdAt: currentMessage.createdAt,
10962
+ sender: currentMessage.sender,
10662
10963
  content: currentContent,
10663
10964
  isComplete: false,
10664
10965
  expectedAnswer: currentMessage.expectedAnswer,
@@ -10676,9 +10977,10 @@
10676
10977
  }
10677
10978
  // Mark message as complete
10678
10979
  const completeMessage = {
10980
+ // channel: 'PROMPTBOOK_CHAT',
10679
10981
  id: currentMessage.id,
10680
- date: currentMessage.date,
10681
- from: currentMessage.from,
10982
+ createdAt: currentMessage.createdAt,
10983
+ sender: currentMessage.sender,
10682
10984
  content: currentMessage.content,
10683
10985
  isComplete: true,
10684
10986
  expectedAnswer: currentMessage.expectedAnswer,
@@ -16005,7 +16307,7 @@
16005
16307
  let threadMessages = [];
16006
16308
  if ('thread' in prompt && Array.isArray(prompt.thread)) {
16007
16309
  threadMessages = prompt.thread.map((msg) => ({
16008
- role: msg.role === 'assistant' ? 'assistant' : 'user',
16310
+ role: msg.sender === 'assistant' ? 'assistant' : 'user',
16009
16311
  content: msg.content,
16010
16312
  }));
16011
16313
  }