llmz 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/DOCS.md +1 -3
  2. package/dist/_baseForOwn-CFhWe_W6.js +48 -0
  3. package/dist/_baseForOwn-buOZDFbK.cjs +103 -0
  4. package/dist/_baseIteratee-CF4qP2a8.cjs +2377 -0
  5. package/dist/_baseIteratee-P_firB7b.js +2138 -0
  6. package/dist/_getPrototype-CG7Dxrrz.js +6 -0
  7. package/dist/_getPrototype-DQDlNVVM.cjs +10 -0
  8. package/dist/_overArg-C5Hy7oCi.cjs +196 -0
  9. package/dist/_overArg-CRYbj1NH.js +155 -0
  10. package/dist/citations.d.ts +11 -11
  11. package/dist/component-BwixNVH8.cjs +73 -0
  12. package/dist/component-DGG7d_Mz.js +44 -0
  13. package/dist/context.d.ts +8 -8
  14. package/dist/custom-client-BPmEoWKu.cjs +2618 -0
  15. package/dist/custom-client-NUoxrFQh.js +2547 -0
  16. package/dist/dual-modes-D_p-jedw.js +2750 -0
  17. package/dist/dual-modes-wAOAlaBS.cjs +2840 -0
  18. package/dist/errors-C962uJdS.cjs +220 -0
  19. package/dist/errors-Cg1G0Awu.js +161 -0
  20. package/dist/execute-BEaq3jkV.cjs +1003 -0
  21. package/dist/execute-DYvFRs54.js +1001 -0
  22. package/dist/exit-BGi0Kk0y.cjs +428 -0
  23. package/dist/exit-CDdxDBRT.js +417 -0
  24. package/dist/index.cjs +1786 -1489
  25. package/dist/index.d.ts +10 -9
  26. package/dist/index.js +1721 -1479
  27. package/dist/index.workerd.js +17534 -16875
  28. package/dist/isEmpty-BhJRCqIF.js +52 -0
  29. package/dist/isEmpty-LY533Wmh.cjs +57 -0
  30. package/dist/isPlainObject-CSxXVKCk.cjs +56 -0
  31. package/dist/isPlainObject-D39AzPO2.js +51 -0
  32. package/dist/jsx-BWvT6ukg.cjs +75 -0
  33. package/dist/jsx-CIgdGGVs.js +52 -0
  34. package/dist/jsx.d.ts +2 -2
  35. package/dist/prompts/chat-mode/system.md.d.ts +1 -1
  36. package/dist/prompts/chat-mode/user.md.d.ts +1 -1
  37. package/dist/prompts/worker-mode/system.md.d.ts +1 -1
  38. package/dist/prompts/worker-mode/user.md.d.ts +1 -1
  39. package/dist/quickjs-variant-BYhMBpwU.js +45 -0
  40. package/dist/quickjs-variant-CsIwTVFC.cjs +56 -0
  41. package/dist/quickjs-variant.workerd.d.ts +1 -1
  42. package/dist/result.d.ts +12 -12
  43. package/dist/rolldown-runtime-EAsCxrDo.js +14 -0
  44. package/dist/runtime/interpret-result.d.ts +1 -1
  45. package/dist/snapshots.d.ts +5 -5
  46. package/dist/stack-traces-BIE_5Xwf.js +21 -0
  47. package/dist/stack-traces-ntw_qhoy.cjs +26 -0
  48. package/dist/tool-CAo-BQHs.js +643 -0
  49. package/dist/tool-DdPZb0JW.cjs +654 -0
  50. package/dist/tool.d.ts +3 -3
  51. package/dist/truncator-B6aaJaN1.cjs +276 -0
  52. package/dist/truncator-DZqEqnpD.js +253 -0
  53. package/dist/typings-BwAz_TM9.cjs +784 -0
  54. package/dist/typings-CrBa7Tyy.js +743 -0
  55. package/dist/uniq-BYQ7GWwb.js +183 -0
  56. package/dist/uniq-G872RWmE.cjs +200 -0
  57. package/dist/utils-UBeAFeEI.js +950 -0
  58. package/dist/utils-ZpJm00ed.cjs +1075 -0
  59. package/dist/vm/errors.d.ts +2 -2
  60. package/dist/vm-BjkJqSQH.cjs +3438 -0
  61. package/dist/vm-C5vf1LH3.js +3436 -0
  62. package/package.json +7 -7
  63. package/dist/chunk-34GJUS6U.js +0 -3266
  64. package/dist/chunk-3UZKLXAD.cjs +0 -3249
  65. package/dist/chunk-4POZJQXN.js +0 -1530
  66. package/dist/chunk-5WBNTV42.cjs +0 -1530
  67. package/dist/chunk-5ZF6NTYI.cjs +0 -33
  68. package/dist/chunk-72ZWBNZV.js +0 -173
  69. package/dist/chunk-DDSJTR6Q.cjs +0 -257
  70. package/dist/chunk-GDJTKI7J.js +0 -792
  71. package/dist/chunk-GLXADNTR.js +0 -199
  72. package/dist/chunk-GOWPACSK.cjs +0 -199
  73. package/dist/chunk-HB2G32AK.js +0 -257
  74. package/dist/chunk-HC2QZTVT.cjs +0 -3266
  75. package/dist/chunk-HEAQAEFZ.cjs +0 -173
  76. package/dist/chunk-HMMM32RG.cjs +0 -792
  77. package/dist/chunk-I56MPOVG.cjs +0 -62
  78. package/dist/chunk-KIN7Y247.cjs +0 -32
  79. package/dist/chunk-KTDBAJBB.cjs +0 -1685
  80. package/dist/chunk-KWQTYXAT.js +0 -62
  81. package/dist/chunk-LOX7GOR6.js +0 -1685
  82. package/dist/chunk-PK72FAKD.cjs +0 -175
  83. package/dist/chunk-PZE6PIPG.cjs +0 -621
  84. package/dist/chunk-RGUG3UMF.cjs +0 -26
  85. package/dist/chunk-TDALRNGL.js +0 -621
  86. package/dist/chunk-UGHFNCPD.js +0 -26
  87. package/dist/chunk-WSVDMGMR.js +0 -175
  88. package/dist/chunk-XTEHT2TK.js +0 -33
  89. package/dist/chunk-YEAWWJSJ.js +0 -32
  90. package/dist/chunk-YRS7KRKP.js +0 -3249
  91. package/dist/component-2NYFY6CW.cjs +0 -14
  92. package/dist/component-ASNZHQUR.js +0 -14
  93. package/dist/dual-modes-S5TJ5JVJ.js +0 -10
  94. package/dist/dual-modes-TCMWBZIH.cjs +0 -10
  95. package/dist/execute-FF7D46TY.js +0 -1109
  96. package/dist/execute-IK6O4SU2.cjs +0 -1109
  97. package/dist/exit-MX56VN2C.cjs +0 -8
  98. package/dist/exit-UQ3EUX5D.js +0 -8
  99. package/dist/jsx-DDZ63UUF.js +0 -13
  100. package/dist/jsx-ULPWX5TW.cjs +0 -13
  101. package/dist/tool-KD7FL45V.js +0 -11
  102. package/dist/tool-VE2YHIY2.cjs +0 -11
  103. package/dist/truncator-73RCL52Y.js +0 -12
  104. package/dist/truncator-FZNLYSDL.cjs +0 -12
  105. package/dist/typings-E2RROCLT.js +0 -10
  106. package/dist/typings-LQOBZXSO.cjs +0 -10
  107. package/dist/utils-IATCUNKF.js +0 -43
  108. package/dist/utils-ITB4NEL7.cjs +0 -43
  109. package/dist/vm-6D3IIIU7.cjs +0 -12
  110. package/dist/vm-QO5FSGPN.js +0 -12
package/dist/index.cjs CHANGED
@@ -1,1555 +1,1852 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class; var _class2; var _class3; var _class4;
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
- var _chunk5WBNTV42cjs = require('./chunk-5WBNTV42.cjs');
14
-
15
-
16
-
17
-
18
-
19
-
20
- var _chunkKTDBAJBBcjs = require('./chunk-KTDBAJBB.cjs');
21
-
22
-
23
- var _chunkRGUG3UMFcjs = require('./chunk-RGUG3UMF.cjs');
24
-
25
-
26
- var _chunkPZE6PIPGcjs = require('./chunk-PZE6PIPG.cjs');
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
- var _chunkHMMM32RGcjs = require('./chunk-HMMM32RG.cjs');
35
-
36
-
37
-
38
-
39
-
40
- var _chunkPK72FAKDcjs = require('./chunk-PK72FAKD.cjs');
41
- require('./chunk-KIN7Y247.cjs');
42
-
43
-
44
- var _chunkDDSJTR6Qcjs = require('./chunk-DDSJTR6Q.cjs');
45
-
46
-
47
-
48
-
49
-
50
- var _chunkI56MPOVGcjs = require('./chunk-I56MPOVG.cjs');
51
- require('./chunk-5ZF6NTYI.cjs');
52
-
53
-
54
-
55
-
56
- var _chunkHEAQAEFZcjs = require('./chunk-HEAQAEFZ.cjs');
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
- var _chunkGOWPACSKcjs = require('./chunk-GOWPACSK.cjs');
67
-
68
-
69
- var _chunkHC2QZTVTcjs = require('./chunk-HC2QZTVT.cjs');
70
-
71
- // package.json
72
- var version = "0.6.0";
73
-
74
- // src/objects.ts
75
- var _zui = require('@bpinternal/zui');
76
-
77
- // src/hoist.ts
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_dual_modes = require("./dual-modes-wAOAlaBS.cjs");
3
+ const require_custom_client = require("./custom-client-BPmEoWKu.cjs");
4
+ const require_utils = require("./utils-ZpJm00ed.cjs");
5
+ const require_tool = require("./tool-DdPZb0JW.cjs");
6
+ const require_errors = require("./errors-C962uJdS.cjs");
7
+ const require_typings = require("./typings-BwAz_TM9.cjs");
8
+ const require_exit = require("./exit-BGi0Kk0y.cjs");
9
+ const require_component = require("./component-BwixNVH8.cjs");
10
+ const require_truncator = require("./truncator-B6aaJaN1.cjs");
11
+ const require_quickjs_variant = require("./quickjs-variant-CsIwTVFC.cjs");
12
+ let _bpinternal_zui = require("@bpinternal/zui");
13
+ //#region package.json
14
+ var version = "0.6.2";
15
+ //#endregion
16
+ //#region src/hoist.ts
17
+ /**
18
+ * Hoists object types (`{ ... }`) that appear more than once in a block of
19
+ * typings into named `type` aliases, replacing every occurrence with a
20
+ * reference. Runs repeatedly until a fixpoint so nested duplicates converge.
21
+ */
22
+ /** Prints a node tree back to text, preserving line structure (formatTypings normalizes later) */
78
23
  function printNodes(nodes) {
79
- let out = "";
80
- let afterLineComment = false;
81
- const emit = (n) => {
82
- const newlines = Math.min(_nullishCoalesce(n.nl, () => ( 0)), 2);
83
- if (newlines > 0) {
84
- out += "\n".repeat(newlines);
85
- } else if (afterLineComment) {
86
- out += "\n";
87
- } else if (out.length && !out.endsWith("\n")) {
88
- out += " ";
89
- }
90
- afterLineComment = false;
91
- if (_chunkHMMM32RGcjs.isGroup.call(void 0, n)) {
92
- out += n.open;
93
- for (const child of n.children) {
94
- emit(child);
95
- }
96
- if (afterLineComment) {
97
- out += "\n";
98
- afterLineComment = false;
99
- }
100
- out += n.close;
101
- } else {
102
- out += n.text;
103
- afterLineComment = n.kind === "line-comment";
104
- }
105
- };
106
- for (const n of nodes) {
107
- emit(n);
108
- }
109
- return out;
24
+ let out = "";
25
+ let afterLineComment = false;
26
+ const emit = (n) => {
27
+ const newlines = Math.min(n.nl ?? 0, 2);
28
+ if (newlines > 0) out += "\n".repeat(newlines);
29
+ else if (afterLineComment) out += "\n";
30
+ else if (out.length && !out.endsWith("\n")) out += " ";
31
+ afterLineComment = false;
32
+ if (require_typings.isGroup(n)) {
33
+ out += n.open;
34
+ for (const child of n.children) emit(child);
35
+ if (afterLineComment) {
36
+ out += "\n";
37
+ afterLineComment = false;
38
+ }
39
+ out += n.close;
40
+ } else {
41
+ out += n.text;
42
+ afterLineComment = n.kind === "line-comment";
43
+ }
44
+ };
45
+ for (const n of nodes) emit(n);
46
+ return out;
110
47
  }
48
+ /** Canonical structural key of a type literal: comments and separators ignored */
111
49
  function keyOf(group) {
112
- const parts = [];
113
- const visit = (n) => {
114
- if (_chunkHMMM32RGcjs.isGroup.call(void 0, n)) {
115
- parts.push(n.open);
116
- n.children.forEach(visit);
117
- parts.push(n.close);
118
- } else if (n.kind === "word" || n.kind === "string" || n.kind === "punct" && n.text !== ";" && n.text !== ",") {
119
- parts.push(n.text);
120
- }
121
- };
122
- visit(group);
123
- return parts.join(" ");
50
+ const parts = [];
51
+ const visit = (n) => {
52
+ if (require_typings.isGroup(n)) {
53
+ parts.push(n.open);
54
+ n.children.forEach(visit);
55
+ parts.push(n.close);
56
+ } else if (n.kind === "word" || n.kind === "string" || n.kind === "punct" && n.text !== ";" && n.text !== ",") parts.push(n.text);
57
+ };
58
+ visit(group);
59
+ return parts.join(" ");
124
60
  }
125
- var prevMeaningful = (siblings, index) => {
126
- for (let i = index - 1; i >= 0; i--) {
127
- const n = siblings[i];
128
- if (_chunkHMMM32RGcjs.isGroup.call(void 0, n) || n.kind !== "block-comment" && n.kind !== "line-comment") {
129
- return n;
130
- }
131
- }
132
- return void 0;
61
+ const prevMeaningful = (siblings, index) => {
62
+ for (let i = index - 1; i >= 0; i--) {
63
+ const n = siblings[i];
64
+ if (require_typings.isGroup(n) || n.kind !== "block-comment" && n.kind !== "line-comment") return n;
65
+ }
133
66
  };
134
- var asName = (text) => _chunkHC2QZTVTcjs.upperFirst_default.call(void 0, text.replace(/['"]/g, "").replace(/[^A-Za-z0-9_$]/g, ""));
67
+ const asName = (text) => require_utils.upperFirst(text.replace(/['"]/g, "").replace(/[^A-Za-z0-9_$]/g, ""));
68
+ /** The naming segment for a `{`/`<` group from its surrounding tokens (`key:`, `fn(...)`, `): `, `=>`) */
135
69
  function segmentsAt(siblings, index) {
136
- var _a;
137
- const prev = prevMeaningful(siblings, index);
138
- if (!prev || _chunkHMMM32RGcjs.isGroup.call(void 0, prev)) {
139
- return [];
140
- }
141
- if (_chunkHMMM32RGcjs.isPunct.call(void 0, prev, "=>")) {
142
- return ["Output"];
143
- }
144
- if (_chunkHMMM32RGcjs.isPunct.call(void 0, prev, ":") || _chunkHMMM32RGcjs.isPunct.call(void 0, prev, "<")) {
145
- let i = siblings.indexOf(prev) - 1;
146
- while (i >= 0 && !_chunkHMMM32RGcjs.isGroup.call(void 0, siblings[i]) && ((_a = siblings[i].kind) == null ? void 0 : _a.includes("comment"))) {
147
- i--;
148
- }
149
- let q = siblings[i];
150
- if (q && !_chunkHMMM32RGcjs.isGroup.call(void 0, q) && q.kind === "punct" && q.text === "?") {
151
- q = siblings[--i];
152
- }
153
- if (q && _chunkHMMM32RGcjs.isGroup.call(void 0, q) && q.open === "(") {
154
- const fnWord = prevMeaningful(siblings, i);
155
- return fnWord && !_chunkHMMM32RGcjs.isGroup.call(void 0, fnWord) && fnWord.kind === "word" ? [asName(fnWord.text), "Output"] : ["Output"];
156
- }
157
- if (q && !_chunkHMMM32RGcjs.isGroup.call(void 0, q) && (q.kind === "word" || q.kind === "string")) {
158
- return [asName(q.text)];
159
- }
160
- }
161
- return [];
70
+ const prev = prevMeaningful(siblings, index);
71
+ if (!prev || require_typings.isGroup(prev)) return [];
72
+ if (require_typings.isPunct(prev, "=>")) return ["Output"];
73
+ if (require_typings.isPunct(prev, ":") || require_typings.isPunct(prev, "<")) {
74
+ var _kind;
75
+ let i = siblings.indexOf(prev) - 1;
76
+ while (i >= 0 && !require_typings.isGroup(siblings[i]) && ((_kind = siblings[i].kind) === null || _kind === void 0 ? void 0 : _kind.includes("comment"))) i--;
77
+ let q = siblings[i];
78
+ if (q && !require_typings.isGroup(q) && q.kind === "punct" && q.text === "?") q = siblings[--i];
79
+ if (q && require_typings.isGroup(q) && q.open === "(") {
80
+ const fnWord = prevMeaningful(siblings, i);
81
+ return fnWord && !require_typings.isGroup(fnWord) && fnWord.kind === "word" ? [asName(fnWord.text), "Output"] : ["Output"];
82
+ }
83
+ if (q && !require_typings.isGroup(q) && (q.kind === "word" || q.kind === "string")) return [asName(q.text)];
84
+ }
85
+ return [];
162
86
  }
87
+ /**
88
+ * Visits every hoistable `{ ... }` type literal with its naming path. Value
89
+ * objects (after `=`) are skipped — except `type X = { ... }` alias bodies,
90
+ * which are visited with their alias name so they can act as the canonical
91
+ * definition.
92
+ */
163
93
  function walkLiterals(siblings, path, visit) {
164
- var _a;
165
- for (let i = 0; i < siblings.length; i++) {
166
- const node = siblings[i];
167
- if (!_chunkHMMM32RGcjs.isGroup.call(void 0, node)) {
168
- continue;
169
- }
170
- if (node.open === "(") {
171
- const fnWord = prevMeaningful(siblings, i);
172
- const fnName = fnWord && !_chunkHMMM32RGcjs.isGroup.call(void 0, fnWord) && fnWord.kind === "word" ? [asName(fnWord.text)] : [];
173
- walkLiterals(node.children, [...path, ...fnName], visit);
174
- continue;
175
- }
176
- if (node.open === "<" || node.open === "[") {
177
- walkLiterals(node.children, [...path, ...segmentsAt(siblings, i)], visit);
178
- continue;
179
- }
180
- const prev = prevMeaningful(siblings, i);
181
- if (prev && _chunkHMMM32RGcjs.isPunct.call(void 0, prev, "=")) {
182
- const eqIdx = siblings.indexOf(prev);
183
- const nameTok = siblings[eqIdx - 1];
184
- const typeTok = siblings[eqIdx - 2];
185
- const isAlias = nameTok && typeTok && !_chunkHMMM32RGcjs.isGroup.call(void 0, nameTok) && !_chunkHMMM32RGcjs.isGroup.call(void 0, typeTok) && nameTok.kind === "word" && typeTok.kind === "word" && typeTok.text === "type";
186
- if (!isAlias) {
187
- continue;
188
- }
189
- const aliasName = nameTok.text;
190
- visit({ siblings, index: i, group: node, path: [aliasName], aliasName });
191
- if (siblings[i] === node) {
192
- walkLiterals(node.children, [aliasName], visit);
193
- }
194
- continue;
195
- }
196
- const prevIsNamespace = prev && !_chunkHMMM32RGcjs.isGroup.call(void 0, prev) && prev.kind === "word" && ((_a = prevMeaningful(siblings, siblings.indexOf(prev))) == null ? void 0 : _a.kind) === "word";
197
- const namespaceLike = prevIsNamespace && ["namespace", "module"].includes(prevMeaningful(siblings, siblings.indexOf(prev)).text);
198
- const segments = segmentsAt(siblings, i);
199
- const newPath = [...path, ...segments];
200
- if (!namespaceLike) {
201
- visit({ siblings, index: i, group: node, path: newPath });
202
- }
203
- if (siblings[i] === node) {
204
- walkLiterals(node.children, namespaceLike ? [...path, asName(prev.text)] : newPath, visit);
205
- }
206
- }
94
+ for (let i = 0; i < siblings.length; i++) {
95
+ var _prevMeaningful;
96
+ const node = siblings[i];
97
+ if (!require_typings.isGroup(node)) continue;
98
+ if (node.open === "(") {
99
+ const fnWord = prevMeaningful(siblings, i);
100
+ const fnName = fnWord && !require_typings.isGroup(fnWord) && fnWord.kind === "word" ? [asName(fnWord.text)] : [];
101
+ walkLiterals(node.children, [...path, ...fnName], visit);
102
+ continue;
103
+ }
104
+ if (node.open === "<" || node.open === "[") {
105
+ walkLiterals(node.children, [...path, ...segmentsAt(siblings, i)], visit);
106
+ continue;
107
+ }
108
+ const prev = prevMeaningful(siblings, i);
109
+ if (prev && require_typings.isPunct(prev, "=")) {
110
+ const eqIdx = siblings.indexOf(prev);
111
+ const nameTok = siblings[eqIdx - 1];
112
+ const typeTok = siblings[eqIdx - 2];
113
+ if (!(nameTok && typeTok && !require_typings.isGroup(nameTok) && !require_typings.isGroup(typeTok) && nameTok.kind === "word" && typeTok.kind === "word" && typeTok.text === "type")) continue;
114
+ const aliasName = nameTok.text;
115
+ visit({
116
+ siblings,
117
+ index: i,
118
+ group: node,
119
+ path: [aliasName],
120
+ aliasName
121
+ });
122
+ if (siblings[i] === node) walkLiterals(node.children, [aliasName], visit);
123
+ continue;
124
+ }
125
+ const namespaceLike = prev && !require_typings.isGroup(prev) && prev.kind === "word" && ((_prevMeaningful = prevMeaningful(siblings, siblings.indexOf(prev))) === null || _prevMeaningful === void 0 ? void 0 : _prevMeaningful.kind) === "word" && ["namespace", "module"].includes(prevMeaningful(siblings, siblings.indexOf(prev)).text);
126
+ const segments = segmentsAt(siblings, i);
127
+ const newPath = [...path, ...segments];
128
+ if (!namespaceLike) visit({
129
+ siblings,
130
+ index: i,
131
+ group: node,
132
+ path: newPath
133
+ });
134
+ if (siblings[i] === node) walkLiterals(node.children, namespaceLike ? [...path, asName(prev.text)] : newPath, visit);
135
+ }
207
136
  }
208
137
  function extractAndHoistTypes(code) {
209
- const top = _chunkHMMM32RGcjs.parse.call(void 0, _chunkHMMM32RGcjs.tokenize.call(void 0, code));
210
- const counts = /* @__PURE__ */ new Map();
211
- const aliasByKey = /* @__PURE__ */ new Map();
212
- const usedNames = /* @__PURE__ */ new Set();
213
- walkLiterals(top, [], ({ group, path, aliasName }) => {
214
- const key = keyOf(group);
215
- counts.set(key, (_nullishCoalesce(counts.get(key), () => ( 0))) + 1);
216
- if (aliasName && !aliasByKey.has(key)) {
217
- aliasByKey.set(key, aliasName);
218
- }
219
- for (const segment of path) {
220
- usedNames.add(segment);
221
- }
222
- if (aliasName) {
223
- usedNames.add(aliasName);
224
- }
225
- });
226
- const uniqueName = (base) => {
227
- let name = base;
228
- let counter = 1;
229
- while (usedNames.has(name)) {
230
- name = `${base}${counter++}`;
231
- }
232
- usedNames.add(name);
233
- return name;
234
- };
235
- const newAliases = [];
236
- walkLiterals(top, [], ({ siblings, index, group, aliasName, path }) => {
237
- const key = keyOf(group);
238
- if ((_nullishCoalesce(counts.get(key), () => ( 0))) < 2 || aliasName) {
239
- return;
240
- }
241
- let name = aliasByKey.get(key);
242
- if (!name) {
243
- const deduped = [...new Set(path)];
244
- name = uniqueName(deduped.length ? deduped.join("") : "UnnamedType");
245
- aliasByKey.set(key, name);
246
- newAliases.push(`type ${name} = ${printNodes([{ ...group, nl: 0 }])}`);
247
- }
248
- siblings[index] = { kind: "word", text: name, nl: group.nl };
249
- });
250
- const body = printNodes(top);
251
- return newAliases.length ? `${newAliases.join("\n")}
252
- ${body}` : body;
138
+ const top = require_typings.parse(require_typings.tokenize(code));
139
+ const counts = /* @__PURE__ */ new Map();
140
+ const aliasByKey = /* @__PURE__ */ new Map();
141
+ const usedNames = /* @__PURE__ */ new Set();
142
+ walkLiterals(top, [], ({ group, path, aliasName }) => {
143
+ const key = keyOf(group);
144
+ counts.set(key, (counts.get(key) ?? 0) + 1);
145
+ if (aliasName && !aliasByKey.has(key)) aliasByKey.set(key, aliasName);
146
+ for (const segment of path) usedNames.add(segment);
147
+ if (aliasName) usedNames.add(aliasName);
148
+ });
149
+ const uniqueName = (base) => {
150
+ let name = base;
151
+ let counter = 1;
152
+ while (usedNames.has(name)) name = `${base}${counter++}`;
153
+ usedNames.add(name);
154
+ return name;
155
+ };
156
+ const newAliases = [];
157
+ walkLiterals(top, [], ({ siblings, index, group, aliasName, path }) => {
158
+ const key = keyOf(group);
159
+ if ((counts.get(key) ?? 0) < 2 || aliasName) return;
160
+ let name = aliasByKey.get(key);
161
+ if (!name) {
162
+ const deduped = [...new Set(path)];
163
+ name = uniqueName(deduped.length ? deduped.join("") : "UnnamedType");
164
+ aliasByKey.set(key, name);
165
+ newAliases.push(`type ${name} = ${printNodes([{
166
+ ...group,
167
+ nl: 0
168
+ }])}`);
169
+ }
170
+ siblings[index] = {
171
+ kind: "word",
172
+ text: name,
173
+ nl: group.nl
174
+ };
175
+ });
176
+ const body = printNodes(top);
177
+ return newAliases.length ? `${newAliases.join("\n")}\n${body}` : body;
253
178
  }
254
179
  async function hoistTypings(code, formatOptions) {
255
- formatOptions ??= {};
256
- formatOptions.throwOnError ??= true;
257
- for (let i = 1; i <= 5; i++) {
258
- try {
259
- const initialCode = code;
260
- code = extractAndHoistTypes(code);
261
- if (initialCode === code) {
262
- break;
263
- }
264
- } catch (err) {
265
- console.error(err);
266
- if (formatOptions.throwOnError) {
267
- throw new (0, _chunkPK72FAKDcjs.CodeFormattingError)(err instanceof Error ? err.message : String(_nullishCoalesce(err, () => ( "Unknown Error"))), code);
268
- }
269
- break;
270
- }
271
- }
272
- return _chunkHMMM32RGcjs.formatTypings.call(void 0, code, formatOptions);
180
+ formatOptions ??= {};
181
+ formatOptions.throwOnError ??= true;
182
+ for (let i = 1; i <= 5; i++) try {
183
+ const initialCode = code;
184
+ code = extractAndHoistTypes(code);
185
+ if (initialCode === code) break;
186
+ } catch (err) {
187
+ console.error(err);
188
+ if (formatOptions.throwOnError) throw new require_errors.CodeFormattingError(err instanceof Error ? err.message : String(err ?? "Unknown Error"), code);
189
+ break;
190
+ }
191
+ return require_typings.formatTypings(code, formatOptions);
273
192
  }
274
-
275
- // src/objects.ts
276
- var LARGE_OBJECT_LINES_OF_CODE = 10;
193
+ //#endregion
194
+ //#region src/objects.ts
195
+ /** How many lines of code an object needs to have before we insert a comment for end tag */
196
+ const LARGE_OBJECT_LINES_OF_CODE = 10;
197
+ /**
198
+ * ObjectInstance creates stateful, namespace-scoped objects for LLMz agents.
199
+ *
200
+ * Objects combine properties (stateful variables) and tools (functions) into a
201
+ * single namespace that the LLM can interact with. This provides organized,
202
+ * type-safe interfaces for complex data and functionality.
203
+ *
204
+ * ## Key Features
205
+ * - **Stateful Properties**: Variables that persist across execution iterations
206
+ * - **Validation**: Zod schema validation for property changes
207
+ * - **Tool Grouping**: Organize related tools under a common namespace
208
+ * - **Type Safety**: Full TypeScript inference and validation
209
+ * - **Dynamic Updates**: Properties can reflect real-time state changes
210
+ *
211
+ * ## Use Cases
212
+ * - **User Profile Management**: Collect and validate user data over time
213
+ * - **API Namespacing**: Group related API calls under a common interface
214
+ * - **State Machines**: Track and modify execution state
215
+ * - **Configuration Objects**: Manage settings and preferences
216
+ * - **Multi-Agent Systems**: Per-agent state and capabilities
217
+ *
218
+ * ## Basic Usage
219
+ *
220
+ * ### Simple Property Object
221
+ * ```typescript
222
+ * const userProfile = new ObjectInstance({
223
+ * name: 'user',
224
+ * description: 'User profile data',
225
+ * properties: [
226
+ * {
227
+ * name: 'name',
228
+ * value: 'John Doe',
229
+ * type: z.string().min(1),
230
+ * writable: true,
231
+ * },
232
+ * {
233
+ * name: 'email',
234
+ * value: null,
235
+ * type: z.string().email().nullable(),
236
+ * writable: true,
237
+ * },
238
+ * {
239
+ * name: 'id',
240
+ * value: 'user_123',
241
+ * writable: false, // Read-only
242
+ * },
243
+ * ],
244
+ * })
245
+ *
246
+ * // LLM can access and modify: user.name, user.email
247
+ * // LLM can read only: user.id
248
+ * ```
249
+ *
250
+ * ### Tool Grouping
251
+ * ```typescript
252
+ * const fileSystem = new ObjectInstance({
253
+ * name: 'fs',
254
+ * description: 'File system operations',
255
+ * tools: [
256
+ * new Tool({
257
+ * name: 'readFile',
258
+ * input: z.object({ path: z.string() }),
259
+ * output: z.string(),
260
+ * handler: async ({ path }) => readFileSync(path, 'utf8'),
261
+ * }),
262
+ * new Tool({
263
+ * name: 'writeFile',
264
+ * input: z.object({ path: z.string(), content: z.string() }),
265
+ * handler: async ({ path, content }) => writeFileSync(path, content),
266
+ * }),
267
+ * ],
268
+ * })
269
+ *
270
+ * // LLM can call: fs.readFile(), fs.writeFile()
271
+ * ```
272
+ *
273
+ * ### Combined Properties and Tools
274
+ * ```typescript
275
+ * const database = new ObjectInstance({
276
+ * name: 'db',
277
+ * description: 'Database connection with state',
278
+ * properties: [
279
+ * {
280
+ * name: 'connectionString',
281
+ * value: 'postgresql://localhost:5432/mydb',
282
+ * writable: false,
283
+ * },
284
+ * {
285
+ * name: 'lastQuery',
286
+ * value: null,
287
+ * type: z.string().nullable(),
288
+ * writable: true,
289
+ * },
290
+ * ],
291
+ * tools: [
292
+ * new Tool({
293
+ * name: 'query',
294
+ * input: z.object({ sql: z.string() }),
295
+ * output: z.array(z.record(z.any())),
296
+ * handler: async ({ sql }) => {
297
+ * // Execute query and update lastQuery property
298
+ * const results = await executeQuery(sql)
299
+ * return results
300
+ * },
301
+ * }),
302
+ * ],
303
+ * })
304
+ * ```
305
+ *
306
+ * ## Dynamic Objects
307
+ *
308
+ * Objects can be created dynamically to reflect current state:
309
+ *
310
+ * ```typescript
311
+ * const memory: Record<string, any> = {}
312
+ *
313
+ * const getObjects = () => [
314
+ * new ObjectInstance({
315
+ * name: 'user',
316
+ * properties: [
317
+ * {
318
+ * name: 'name',
319
+ * value: memory.name ?? null,
320
+ * type: z.string().nullable(),
321
+ * writable: true,
322
+ * },
323
+ * {
324
+ * name: 'age',
325
+ * value: memory.age ?? null,
326
+ * type: z.number().min(18).max(100).nullable(),
327
+ * writable: true,
328
+ * },
329
+ * ],
330
+ * }),
331
+ * ]
332
+ *
333
+ * await execute({
334
+ * objects: getObjects, // Function returning current state
335
+ * onTrace: ({ trace }) => {
336
+ * if (trace.type === 'property') {
337
+ * // Persist property changes
338
+ * memory[trace.property] = trace.value
339
+ * }
340
+ * },
341
+ * // ...
342
+ * })
343
+ * ```
344
+ *
345
+ * ## Property Validation
346
+ *
347
+ * Properties support comprehensive validation through Zod schemas:
348
+ *
349
+ * ```typescript
350
+ * const userSettings = new ObjectInstance({
351
+ * name: 'settings',
352
+ * properties: [
353
+ * {
354
+ * name: 'theme',
355
+ * value: 'light',
356
+ * type: z.enum(['light', 'dark']),
357
+ * writable: true,
358
+ * },
359
+ * {
360
+ * name: 'maxRetries',
361
+ * value: 3,
362
+ * type: z.number().min(1).max(10),
363
+ * writable: true,
364
+ * },
365
+ * {
366
+ * name: 'email',
367
+ * value: null,
368
+ * type: z.string().email().nullable(),
369
+ * writable: true,
370
+ * },
371
+ * ],
372
+ * })
373
+ * ```
374
+ *
375
+ * ## TypeScript Integration
376
+ *
377
+ * Objects generate TypeScript namespace declarations:
378
+ *
379
+ * ```typescript
380
+ * // Generated types for the LLM context:
381
+ * export namespace user {
382
+ * const name: Writable<string | null> = null
383
+ * const age: Writable<number | null> = null
384
+ * const id: Readonly<string> = "user_123"
385
+ * }
386
+ *
387
+ * export namespace fs {
388
+ * function readFile(args: { path: string }): Promise<string>
389
+ * function writeFile(args: { path: string, content: string }): Promise<void>
390
+ * }
391
+ * ```
392
+ *
393
+ * @see {@link https://github.com/botpress/botpress/blob/master/packages/llmz/examples/09_chat_variables/index.ts} Example usage
394
+ */
277
395
  var ObjectInstance = class {
278
-
279
-
280
-
281
-
282
-
283
- /**
284
- * Creates a new ObjectInstance.
285
- *
286
- * @param props - Object configuration
287
- * @param props.name - Unique object name (must be valid TypeScript identifier)
288
- * @param props.description - Human-readable description of the object
289
- * @param props.tools - Array of tools to group under this object namespace
290
- * @param props.properties - Array of stateful properties for this object
291
- * @param props.metadata - Additional metadata for the object
292
- *
293
- * @throws Error if name is not a valid identifier
294
- * @throws Error if description is not a string
295
- * @throws Error if metadata is not an object
296
- * @throws Error if properties/tools are not arrays
297
- * @throws Error if properties exceed 100 limit
298
- * @throws Error if property names are duplicated or invalid
299
- * @throws Error if property descriptions exceed 5000 characters
300
- *
301
- * @example
302
- * ```typescript
303
- * const userProfile = new ObjectInstance({
304
- * name: 'user',
305
- * description: 'User profile management',
306
- * properties: [
307
- * {
308
- * name: 'name',
309
- * value: 'John Doe',
310
- * type: z.string().min(1),
311
- * description: 'User full name',
312
- * writable: true,
313
- * },
314
- * {
315
- * name: 'email',
316
- * value: null,
317
- * type: z.string().email().nullable(),
318
- * description: 'User email address',
319
- * writable: true,
320
- * },
321
- * ],
322
- * tools: [
323
- * new Tool({
324
- * name: 'updateProfile',
325
- * input: z.object({ name: z.string(), email: z.string() }),
326
- * handler: async ({ name, email }) => {
327
- * // Update external system
328
- * await updateUserInDatabase({ name, email })
329
- * },
330
- * }),
331
- * ],
332
- * metadata: {
333
- * version: '1.0',
334
- * category: 'user-management',
335
- * },
336
- * })
337
- * ```
338
- */
339
- constructor(props) {
340
- var _a;
341
- if (!_chunkGOWPACSKcjs.isValidIdentifier.call(void 0, props.name)) {
342
- throw new Error(
343
- `Invalid name for tool ${props.name}. A tool name must start with a letter and contain only letters, numbers, and underscores. It must be 1-50 characters long.`
344
- );
345
- }
346
- if (props.description !== void 0 && typeof props.description !== "string") {
347
- throw new Error(
348
- `Invalid description for tool ${props.name}. Expected a string, but got type "${typeof props.description}"`
349
- );
350
- }
351
- if (props.metadata !== void 0 && typeof props.metadata !== "object") {
352
- throw new Error(
353
- `Invalid metadata for tool ${props.name}. Expected an object, but got type "${typeof props.metadata}"`
354
- );
355
- }
356
- if (props.properties !== void 0 && !Array.isArray(props.properties)) {
357
- throw new Error(
358
- `Invalid properties for tool ${props.name}. Expected an array, but got type "${typeof props.properties}"`
359
- );
360
- }
361
- if (props.tools !== void 0 && !Array.isArray(props.tools)) {
362
- throw new Error(`Invalid tools for tool ${props.name}. Expected an array, but got type "${typeof props.tools}"`);
363
- }
364
- if ((_a = props.properties) == null ? void 0 : _a.length) {
365
- if (props.properties.length > 100) {
366
- throw new Error(
367
- `Too many properties for tool ${props.name}. Expected at most 100 properties, but got ${props.properties.length}`
368
- );
369
- }
370
- for (const prop of props.properties) {
371
- if (props.properties.filter((p) => p.name === prop.name).length > 1) {
372
- throw new Error(`Duplicate property name "${prop.name}" in tool ${props.name}`);
373
- }
374
- if (!_chunkGOWPACSKcjs.isValidIdentifier.call(void 0, prop.name)) {
375
- throw new Error(
376
- `Invalid name for property ${prop.name}. A property name must start with a letter and contain only letters, numbers, and underscores. It must be 1-50 characters long.`
377
- );
378
- }
379
- if (prop.description !== void 0 && typeof prop.description !== "string") {
380
- throw new Error(
381
- `Invalid description for property ${prop.name}. Expected a string, but got type "${typeof prop.description}"`
382
- );
383
- }
384
- if (props.description && props.description.length >= 5e3) {
385
- throw new Error(
386
- `Description for property ${prop.name} is too long. Expected at most 5000 characters, but got ${props.description.length}`
387
- );
388
- }
389
- if (typeof prop.writable !== "boolean") {
390
- prop.writable = false;
391
- }
392
- }
393
- }
394
- this.name = props.name;
395
- this.description = props.description;
396
- this.metadata = _nullishCoalesce(props.metadata, () => ( {}));
397
- this.properties = props.properties;
398
- this.tools = _chunkPZE6PIPGcjs.Tool.withUniqueNames(_nullishCoalesce(props.tools, () => ( [])));
399
- }
400
- /**
401
- * Generates TypeScript namespace declarations for this object.
402
- *
403
- * This method creates TypeScript definitions that are included in the LLM context
404
- * to help it understand the available properties and tools. Properties become
405
- * const declarations with appropriate Readonly/Writable types, and tools become
406
- * function signatures.
407
- *
408
- * @returns Promise resolving to TypeScript namespace declaration
409
- *
410
- * @example
411
- * ```typescript
412
- * const obj = new ObjectInstance({
413
- * name: 'user',
414
- * properties: [
415
- * { name: 'name', value: 'John', writable: true },
416
- * { name: 'id', value: 123, writable: false },
417
- * ],
418
- * tools: [
419
- * new Tool({
420
- * name: 'save',
421
- * input: z.object({ data: z.string() }),
422
- * handler: async ({ data }) => { /* ... *\/ },
423
- * }),
424
- * ],
425
- * })
426
- *
427
- * const typings = await obj.getTypings()
428
- * console.log(typings)
429
- * // Output:
430
- * // export namespace user {
431
- * // const name: Writable<string> = "John"
432
- * // const id: Readonly<number> = 123
433
- * // function save(args: { data: string }): Promise<void>
434
- * // }
435
- * ```
436
- */
437
- async getTypings() {
438
- return getObjectTypings(this).withProperties().withTools().build();
439
- }
440
- /**
441
- * Converts this ObjectInstance to its JSON representation.
442
- *
443
- * This method serializes the object into a JSON format that includes its name,
444
- * description, properties, tools, and metadata. It is used for serialization
445
- * and transmission of the object state.
446
- *
447
- * @returns JSON representation of the ObjectInstance
448
- */
449
- toJSON() {
450
- return {
451
- name: this.name,
452
- description: this.description,
453
- properties: this.properties,
454
- tools: (_nullishCoalesce(this.tools, () => ( []))).map((tool) => tool.toJSON()),
455
- metadata: this.metadata
456
- };
457
- }
396
+ name;
397
+ description;
398
+ properties;
399
+ tools;
400
+ metadata;
401
+ /**
402
+ * Creates a new ObjectInstance.
403
+ *
404
+ * @param props - Object configuration
405
+ * @param props.name - Unique object name (must be valid TypeScript identifier)
406
+ * @param props.description - Human-readable description of the object
407
+ * @param props.tools - Array of tools to group under this object namespace
408
+ * @param props.properties - Array of stateful properties for this object
409
+ * @param props.metadata - Additional metadata for the object
410
+ *
411
+ * @throws Error if name is not a valid identifier
412
+ * @throws Error if description is not a string
413
+ * @throws Error if metadata is not an object
414
+ * @throws Error if properties/tools are not arrays
415
+ * @throws Error if properties exceed 100 limit
416
+ * @throws Error if property names are duplicated or invalid
417
+ * @throws Error if property descriptions exceed 5000 characters
418
+ *
419
+ * @example
420
+ * ```typescript
421
+ * const userProfile = new ObjectInstance({
422
+ * name: 'user',
423
+ * description: 'User profile management',
424
+ * properties: [
425
+ * {
426
+ * name: 'name',
427
+ * value: 'John Doe',
428
+ * type: z.string().min(1),
429
+ * description: 'User full name',
430
+ * writable: true,
431
+ * },
432
+ * {
433
+ * name: 'email',
434
+ * value: null,
435
+ * type: z.string().email().nullable(),
436
+ * description: 'User email address',
437
+ * writable: true,
438
+ * },
439
+ * ],
440
+ * tools: [
441
+ * new Tool({
442
+ * name: 'updateProfile',
443
+ * input: z.object({ name: z.string(), email: z.string() }),
444
+ * handler: async ({ name, email }) => {
445
+ * // Update external system
446
+ * await updateUserInDatabase({ name, email })
447
+ * },
448
+ * }),
449
+ * ],
450
+ * metadata: {
451
+ * version: '1.0',
452
+ * category: 'user-management',
453
+ * },
454
+ * })
455
+ * ```
456
+ */
457
+ constructor(props) {
458
+ var _props$properties;
459
+ if (!require_utils.isValidIdentifier(props.name)) throw new Error(`Invalid name for tool ${props.name}. A tool name must start with a letter and contain only letters, numbers, and underscores. It must be 1-50 characters long.`);
460
+ if (props.description !== void 0 && typeof props.description !== "string") throw new Error(`Invalid description for tool ${props.name}. Expected a string, but got type "${typeof props.description}"`);
461
+ if (props.metadata !== void 0 && typeof props.metadata !== "object") throw new Error(`Invalid metadata for tool ${props.name}. Expected an object, but got type "${typeof props.metadata}"`);
462
+ if (props.properties !== void 0 && !Array.isArray(props.properties)) throw new Error(`Invalid properties for tool ${props.name}. Expected an array, but got type "${typeof props.properties}"`);
463
+ if (props.tools !== void 0 && !Array.isArray(props.tools)) throw new Error(`Invalid tools for tool ${props.name}. Expected an array, but got type "${typeof props.tools}"`);
464
+ if ((_props$properties = props.properties) === null || _props$properties === void 0 ? void 0 : _props$properties.length) {
465
+ if (props.properties.length > 100) throw new Error(`Too many properties for tool ${props.name}. Expected at most 100 properties, but got ${props.properties.length}`);
466
+ for (const prop of props.properties) {
467
+ if (props.properties.filter((p) => p.name === prop.name).length > 1) throw new Error(`Duplicate property name "${prop.name}" in tool ${props.name}`);
468
+ if (!require_utils.isValidIdentifier(prop.name)) throw new Error(`Invalid name for property ${prop.name}. A property name must start with a letter and contain only letters, numbers, and underscores. It must be 1-50 characters long.`);
469
+ if (prop.description !== void 0 && typeof prop.description !== "string") throw new Error(`Invalid description for property ${prop.name}. Expected a string, but got type "${typeof prop.description}"`);
470
+ if (props.description && props.description.length >= 5e3) throw new Error(`Description for property ${prop.name} is too long. Expected at most 5000 characters, but got ${props.description.length}`);
471
+ if (typeof prop.writable !== "boolean") prop.writable = false;
472
+ }
473
+ }
474
+ this.name = props.name;
475
+ this.description = props.description;
476
+ this.metadata = props.metadata ?? {};
477
+ this.properties = props.properties;
478
+ this.tools = require_tool.Tool.withUniqueNames(props.tools ?? []);
479
+ }
480
+ /**
481
+ * Generates TypeScript namespace declarations for this object.
482
+ *
483
+ * This method creates TypeScript definitions that are included in the LLM context
484
+ * to help it understand the available properties and tools. Properties become
485
+ * const declarations with appropriate Readonly/Writable types, and tools become
486
+ * function signatures.
487
+ *
488
+ * @returns Promise resolving to TypeScript namespace declaration
489
+ *
490
+ * @example
491
+ * ```typescript
492
+ * const obj = new ObjectInstance({
493
+ * name: 'user',
494
+ * properties: [
495
+ * { name: 'name', value: 'John', writable: true },
496
+ * { name: 'id', value: 123, writable: false },
497
+ * ],
498
+ * tools: [
499
+ * new Tool({
500
+ * name: 'save',
501
+ * input: z.object({ data: z.string() }),
502
+ * handler: async ({ data }) => { /* ... *\/ },
503
+ * }),
504
+ * ],
505
+ * })
506
+ *
507
+ * const typings = await obj.getTypings()
508
+ * console.log(typings)
509
+ * // Output:
510
+ * // export namespace user {
511
+ * // const name: Writable<string> = "John"
512
+ * // const id: Readonly<number> = 123
513
+ * // function save(args: { data: string }): Promise<void>
514
+ * // }
515
+ * ```
516
+ */
517
+ async getTypings() {
518
+ return getObjectTypings(this).withProperties().withTools().build();
519
+ }
520
+ /**
521
+ * Converts this ObjectInstance to its JSON representation.
522
+ *
523
+ * This method serializes the object into a JSON format that includes its name,
524
+ * description, properties, tools, and metadata. It is used for serialization
525
+ * and transmission of the object state.
526
+ *
527
+ * @returns JSON representation of the ObjectInstance
528
+ */
529
+ toJSON() {
530
+ return {
531
+ name: this.name,
532
+ description: this.description,
533
+ properties: this.properties,
534
+ tools: (this.tools ?? []).map((tool) => tool.toJSON()),
535
+ metadata: this.metadata
536
+ };
537
+ }
458
538
  };
539
+ /**
540
+ * Creates a TypeScript namespace builder for an ObjectInstance.
541
+ *
542
+ * This function provides a fluent API for generating TypeScript declarations
543
+ * that include properties, tools, or both. It's used internally by ObjectInstance.getTypings().
544
+ *
545
+ * @param obj - The ObjectInstance to generate typings for
546
+ * @returns A builder object with methods to configure and build the namespace
547
+ * @internal
548
+ */
459
549
  function getObjectTypings(obj) {
460
- let includeProperties = false;
461
- let includeTools = false;
462
- let hoisting = false;
463
- const typings = [];
464
- const addProperties = async () => {
465
- var _a;
466
- if (includeProperties && ((_a = obj.properties) == null ? void 0 : _a.length)) {
467
- typings.push("");
468
- typings.push("// ---------------- //");
469
- typings.push("// Properties //");
470
- typings.push("// ---------------- //");
471
- typings.push("");
472
- for (const prop of _nullishCoalesce(obj.properties, () => ( []))) {
473
- const description = _nullishCoalesce(prop.description, () => ( ""));
474
- if (description == null ? void 0 : description.trim().length) {
475
- typings.push(_chunkGOWPACSKcjs.getMultilineComment.call(void 0, description));
476
- }
477
- let type = "unknown";
478
- if (prop.type) {
479
- type = await _chunkHMMM32RGcjs.getTypings.call(void 0, prop.type, {});
480
- } else if (prop.value !== void 0) {
481
- type = typeof prop.value;
482
- }
483
- type = prop.writable ? `Writable<${type}>` : `Readonly<${type}>`;
484
- const value = embedPropertyValue(prop);
485
- typings.push(`const ${prop.name}: ${type} = ${value}`);
486
- }
487
- }
488
- };
489
- const addTools = async () => {
490
- var _a;
491
- if (includeTools && ((_a = obj.tools) == null ? void 0 : _a.length)) {
492
- typings.push("");
493
- typings.push("// ---------------- //");
494
- typings.push("// Tools //");
495
- typings.push("// ---------------- //");
496
- typings.push("");
497
- for (const tool of obj.tools) {
498
- const fnType = _zui.z.function(tool.zInput, tool.zOutput).title(tool.name).describe(_nullishCoalesce(tool.description, () => ( "")));
499
- let temp = await _chunkHMMM32RGcjs.getTypings.call(void 0, fnType, {
500
- declaration: true
501
- });
502
- temp = temp.replace("declare function ", "function ");
503
- typings.push(temp);
504
- }
505
- }
506
- };
507
- const finalize = async () => {
508
- var _a;
509
- let closingBracket = "";
510
- if (typings.length >= LARGE_OBJECT_LINES_OF_CODE) {
511
- closingBracket = ` // end namespace "${obj.name}"`;
512
- }
513
- let body = typings.join("\n");
514
- if (hoisting) {
515
- body = await hoistTypings(body, { throwOnError: false });
516
- }
517
- typings.push("}" + closingBracket);
518
- let header = "";
519
- if ((_a = obj.description) == null ? void 0 : _a.trim().length) {
520
- header = _chunkGOWPACSKcjs.getMultilineComment.call(void 0, obj.description);
521
- }
522
- return _chunkHMMM32RGcjs.formatTypings.call(void 0,
523
- `${header}
550
+ let includeProperties = false;
551
+ let includeTools = false;
552
+ let hoisting = false;
553
+ const typings = [];
554
+ const addProperties = async () => {
555
+ var _obj$properties;
556
+ if (includeProperties && ((_obj$properties = obj.properties) === null || _obj$properties === void 0 ? void 0 : _obj$properties.length)) {
557
+ typings.push("");
558
+ typings.push("// ---------------- //");
559
+ typings.push("// Properties //");
560
+ typings.push("// ---------------- //");
561
+ typings.push("");
562
+ for (const prop of obj.properties ?? []) {
563
+ const description = prop.description ?? "";
564
+ if (description === null || description === void 0 ? void 0 : description.trim().length) typings.push(require_utils.getMultilineComment(description));
565
+ let type = "unknown";
566
+ if (prop.type) type = await require_typings.getTypings(prop.type, {});
567
+ else if (prop.value !== void 0) type = typeof prop.value;
568
+ type = prop.writable ? `Writable<${type}>` : `Readonly<${type}>`;
569
+ const value = embedPropertyValue(prop);
570
+ typings.push(`const ${prop.name}: ${type} = ${value}`);
571
+ }
572
+ }
573
+ };
574
+ const addTools = async () => {
575
+ var _obj$tools;
576
+ if (includeTools && ((_obj$tools = obj.tools) === null || _obj$tools === void 0 ? void 0 : _obj$tools.length)) {
577
+ typings.push("");
578
+ typings.push("// ---------------- //");
579
+ typings.push("// Tools //");
580
+ typings.push("// ---------------- //");
581
+ typings.push("");
582
+ for (const tool of obj.tools) {
583
+ const fnType = _bpinternal_zui.z.function(tool.zInput, tool.zOutput).title(tool.name).describe(tool.description ?? "");
584
+ let temp = await require_typings.getTypings(fnType, { declaration: true });
585
+ temp = temp.replace("declare function ", "function ");
586
+ typings.push(temp);
587
+ }
588
+ }
589
+ };
590
+ const finalize = async () => {
591
+ var _obj$description;
592
+ let closingBracket = "";
593
+ if (typings.length >= LARGE_OBJECT_LINES_OF_CODE) closingBracket = ` // end namespace "${obj.name}"`;
594
+ let body = typings.join("\n");
595
+ if (hoisting) body = await hoistTypings(body, { throwOnError: false });
596
+ typings.push("}" + closingBracket);
597
+ let header = "";
598
+ if ((_obj$description = obj.description) === null || _obj$description === void 0 ? void 0 : _obj$description.trim().length) header = require_utils.getMultilineComment(obj.description);
599
+ return require_typings.formatTypings(`${header}
524
600
  export namespace ${obj.name} {
525
601
  ${body}
526
- } ${closingBracket}`.trim(),
527
- { throwOnError: false }
528
- );
529
- };
530
- const api = {
531
- withProperties: () => {
532
- includeProperties = true;
533
- return api;
534
- },
535
- withTools: () => {
536
- includeTools = true;
537
- return api;
538
- },
539
- withHoisting: () => {
540
- hoisting = true;
541
- return api;
542
- },
543
- async build() {
544
- await addProperties();
545
- await addTools();
546
- return finalize();
547
- }
548
- };
549
- return api;
602
+ } ${closingBracket}`.trim(), { throwOnError: false });
603
+ };
604
+ const api = {
605
+ withProperties: () => {
606
+ includeProperties = true;
607
+ return api;
608
+ },
609
+ withTools: () => {
610
+ includeTools = true;
611
+ return api;
612
+ },
613
+ withHoisting: () => {
614
+ hoisting = true;
615
+ return api;
616
+ },
617
+ async build() {
618
+ await addProperties();
619
+ await addTools();
620
+ return finalize();
621
+ }
622
+ };
623
+ return api;
550
624
  }
625
+ /**
626
+ * Converts a property value to its TypeScript literal representation.
627
+ *
628
+ * This function handles the serialization of various JavaScript types into
629
+ * TypeScript code that can be embedded in generated namespace declarations.
630
+ * It supports primitives, objects, arrays, dates, regex, and other common types.
631
+ *
632
+ * @param property - The ObjectProperty containing the value to embed
633
+ * @returns String representation of the value for use in TypeScript code
634
+ * @internal
635
+ */
551
636
  function embedPropertyValue(property) {
552
- if (typeof property.value === "string") {
553
- return _chunkGOWPACSKcjs.escapeString.call(void 0, property.value);
554
- }
555
- if (Number.isNaN(property.value)) {
556
- return "NaN";
557
- }
558
- if (typeof property.value === "number" && Number.isInteger(property.value)) {
559
- return property.value.toString();
560
- }
561
- if (typeof property.value === "boolean") {
562
- return property.value.toString();
563
- }
564
- if (Array.isArray(property.value) || typeof property.value === "object") {
565
- return JSON.stringify(property.value);
566
- }
567
- if (property.value instanceof Date) {
568
- return `new Date('${property.value.toISOString()}')`;
569
- }
570
- if (property.value instanceof RegExp) {
571
- return `new RegExp(${_chunkGOWPACSKcjs.escapeString.call(void 0, property.value.source)}, ${_chunkGOWPACSKcjs.escapeString.call(void 0, property.value.flags)})`;
572
- }
573
- if (property.value === null) {
574
- return "null";
575
- }
576
- if (property.value === void 0) {
577
- return "undefined";
578
- }
579
- if (typeof property.value === "function") {
580
- return "function() {}";
581
- }
582
- if (typeof property.value === "symbol") {
583
- return "Symbol()";
584
- }
585
- if (typeof property.value === "bigint") {
586
- return `${property.value}n`;
587
- }
588
- if (property.value instanceof Error) {
589
- return `Error(${_chunkGOWPACSKcjs.escapeString.call(void 0, property.value.message)})`;
590
- }
591
- if (property.value instanceof Map) {
592
- return `new Map(${JSON.stringify(Array.from(property.value.entries()))})`;
593
- }
594
- if (property.value instanceof Set) {
595
- return `new Set(${JSON.stringify(Array.from(property.value.values()))})`;
596
- }
597
- return "unknown";
637
+ if (typeof property.value === "string") return require_utils.escapeString(property.value);
638
+ if (Number.isNaN(property.value)) return "NaN";
639
+ if (typeof property.value === "number" && Number.isInteger(property.value)) return property.value.toString();
640
+ if (typeof property.value === "boolean") return property.value.toString();
641
+ if (Array.isArray(property.value) || typeof property.value === "object") return JSON.stringify(property.value);
642
+ if (property.value instanceof Date) return `new Date('${property.value.toISOString()}')`;
643
+ if (property.value instanceof RegExp) return `new RegExp(${require_utils.escapeString(property.value.source)}, ${require_utils.escapeString(property.value.flags)})`;
644
+ if (property.value === null) return "null";
645
+ if (property.value === void 0) return "undefined";
646
+ if (typeof property.value === "function") return "function() {}";
647
+ if (typeof property.value === "symbol") return "Symbol()";
648
+ if (typeof property.value === "bigint") return `${property.value}n`;
649
+ if (property.value instanceof Error) return `Error(${require_utils.escapeString(property.value.message)})`;
650
+ if (property.value instanceof Map) return `new Map(${JSON.stringify(Array.from(property.value.entries()))})`;
651
+ if (property.value instanceof Set) return `new Set(${JSON.stringify(Array.from(property.value.values()))})`;
652
+ return "unknown";
598
653
  }
599
-
600
- // src/citations.ts
601
- var RARE_SYMBOLS = {
602
- ARROW_UP: "\u2191",
603
- CIRCLE_BULLET: "\u30FB",
604
- STAR_BULLET_FULL: "\u2605",
605
- STAR_BULLET_EMPTY: "\u2606",
606
- ARROW_BULLET: "\u2192",
607
- SQUARE_BULLET: "\u25A0",
608
- TRIANGLE_BULLET: "\u25BA",
609
- OPENING_TAG: "\u3010",
610
- CLOSING_TAG: "\u3011",
611
- SS: "\xA7",
612
- CROSS: "\u2020"
654
+ //#endregion
655
+ //#region src/citations.ts
656
+ /** These are all single-token symbols that are very rare in natural texts, making them suitable for usage within GPT Prompts. */
657
+ const RARE_SYMBOLS = {
658
+ ARROW_UP: "↑",
659
+ CIRCLE_BULLET: "・",
660
+ STAR_BULLET_FULL: "★",
661
+ STAR_BULLET_EMPTY: "☆",
662
+ ARROW_BULLET: "→",
663
+ SQUARE_BULLET: "■",
664
+ TRIANGLE_BULLET: "►",
665
+ OPENING_TAG: "【",
666
+ CLOSING_TAG: "】",
667
+ SS: "§",
668
+ CROSS: "†"
613
669
  };
614
- var CitationsManager = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this); }
615
- __init() {this._citations = /* @__PURE__ */ new Map()}
616
- __init2() {this._nextId = 0}
617
- /**
618
- * Registers a new source and returns the created Citation.
619
- * @param source An object representing the source of the citation.
620
- * @returns The created Citation.
621
- */
622
- registerSource(source) {
623
- const id = this._nextId++;
624
- const tag = `${RARE_SYMBOLS.OPENING_TAG}${id}${RARE_SYMBOLS.CLOSING_TAG}`;
625
- const citation = {
626
- id,
627
- source,
628
- tag
629
- };
630
- this._citations.set(id, citation);
631
- return citation;
632
- }
633
- /**
634
- * Extracts citations from the provided content and cleans the content of citation tags.
635
- * Non-found citations are replaced with a special "Not Found" citation.
636
- * @param content The string content containing citation tags.
637
- * @returns An object containing the cleaned content and an array of found citations.
638
- */
639
- extractCitations(content, replace) {
640
- const citations = [];
641
- const notFoundCitation = {
642
- id: -1,
643
- source: "Not Found",
644
- tag: ""
645
- };
646
- const regex = new RegExp(`${RARE_SYMBOLS.OPENING_TAG}([\\d|\\w|\\s|,]{0,})${RARE_SYMBOLS.CLOSING_TAG}`, "ig");
647
- let match;
648
- const offsets = [];
649
- while ((match = regex.exec(content)) !== null) {
650
- const offset = match.index;
651
- const length = match[0].length;
652
- offsets.push({ start: offset, length });
653
- const multi = (_nullishCoalesce(match[1], () => ( ""))).split(/\D/g).map((s) => s.trim()).filter(Boolean).map((s) => parseInt(s, 10)).filter((s) => !isNaN(s) && s >= 0);
654
- for (const citationId of multi) {
655
- const citation = this._citations.get(citationId);
656
- if (citation) {
657
- citations.push({ ...citation, offset });
658
- } else {
659
- citations.push({ ...notFoundCitation, offset });
660
- }
661
- }
662
- }
663
- const entries = offsets.map((o) => ({
664
- start: o.start,
665
- length: o.length,
666
- citations: citations.filter((x) => x.offset === o.start && x.id !== -1)
667
- })).sort((a, b) => a.start - b.start);
668
- let result = "";
669
- let cursor = 0;
670
- for (const { start, length, citations: citations2 } of entries) {
671
- result += content.slice(cursor, start);
672
- const replacement = citations2.map((citation) => replace ? replace(citation) : "").join("");
673
- result += replacement;
674
- cursor = start + length;
675
- }
676
- result += content.slice(cursor);
677
- return { cleaned: result, citations };
678
- }
679
- /**
680
- * Strips citation tags from the provided content.
681
- * @param content The string content containing citation tags.
682
- * @returns The cleaned content without citation tags.
683
- */
684
- static stripCitationTags(content) {
685
- const regex = new RegExp(`${RARE_SYMBOLS.OPENING_TAG}([\\d|\\w|\\s|,]{0,})${RARE_SYMBOLS.CLOSING_TAG}?`, "g");
686
- return content.replace(regex, "");
687
- }
688
- /**
689
- * Removes citations from a deeply nested plain object and returns a new object with citations removed.
690
- * @param obj The plain object to process.
691
- * @returns A tuple containing the new object and an array of extracted citations with paths.
692
- */
693
- removeCitationsFromObject(obj) {
694
- const result = [];
695
- const processObject = (current, path) => {
696
- if (typeof current === "string") {
697
- const extraction = this.extractCitations(current);
698
- if (extraction.citations.length > 0) {
699
- result.push(...extraction.citations.map((citation) => ({ path, citation })));
700
- }
701
- return extraction.cleaned;
702
- } else if (typeof current === "object" && current !== null) {
703
- const newObject = Array.isArray(current) ? [] : {};
704
- for (const key of Object.keys(current)) {
705
- newObject[key] = processObject(current[key], `${path}.${key}`);
706
- }
707
- return newObject;
708
- }
709
- return current;
710
- };
711
- const newObj = processObject(obj, "root");
712
- return [newObj, result];
713
- }
714
- /**
715
- * Re-adds citations to the cleaned content based on their offsets.
716
- * @param cleaned The cleaned string without citation tags.
717
- * @param citations The array of citations with offsets.
718
- * @returns The string with citation tags re-added.
719
- */
720
- reAddCitations(cleaned, citations) {
721
- let content = cleaned;
722
- citations.sort((a, b) => (_nullishCoalesce(a.offset, () => ( 0))) - (_nullishCoalesce(b.offset, () => ( 0))));
723
- const adjustment = 0;
724
- for (const citation of citations) {
725
- if (citation.offset != null) {
726
- const position = citation.offset + adjustment;
727
- content = content.slice(0, position) + citation.tag + content.slice(position);
728
- }
729
- }
730
- return content;
731
- }
732
- }, _class);
733
-
734
- // src/component.default.ts
735
-
736
- var Button = new (0, _chunkI56MPOVGcjs.Component)({
737
- type: "leaf",
738
- description: "A button component that can perform actions when clicked",
739
- name: "Button",
740
- aliases: ["btn"],
741
- generation: {
742
- usage: "Attach quick actions to a message, e.g. postback choices or a URL to open.",
743
- examples: [{ props: { action: "postback", label: "Buy", value: "buy_product" } }]
744
- },
745
- leaf: {
746
- props: _zui.z.object({
747
- action: _zui.z.enum(["say", "url", "postback"]).default("say").describe('The action to perform when the button is clicked. Can be "say", "url", or "postback"'),
748
- label: _zui.z.string().describe("The text displayed on the button (min 1 character, max 250 characters)"),
749
- value: _zui.z.string().optional().describe('The postback value to send when the button is clicked. Required if action is "postback"'),
750
- url: _zui.z.string().optional().describe('The URL to open when the button is clicked. Required if action is "url"')
751
- })
752
- }
753
- });
754
- var Image = new (0, _chunkI56MPOVGcjs.Component)({
755
- type: "leaf",
756
- name: "Image",
757
- description: "Displays an image from a URL.",
758
- aliases: [],
759
- generation: {
760
- examples: [{ props: { url: "https://example.com/photo.jpg", alt: "Example image" } }]
761
- },
762
- leaf: {
763
- props: _zui.z.object({
764
- url: _zui.z.string().describe("The URL of the image (must be valid)"),
765
- alt: _zui.z.string().optional().describe("Alternative text describing the image")
766
- })
767
- }
670
+ var CitationsManager = class {
671
+ _citations = /* @__PURE__ */ new Map();
672
+ _nextId = 0;
673
+ /**
674
+ * Registers a new source and returns the created Citation.
675
+ * @param source An object representing the source of the citation.
676
+ * @returns The created Citation.
677
+ */
678
+ registerSource(source) {
679
+ const id = this._nextId++;
680
+ const citation = {
681
+ id,
682
+ source,
683
+ tag: `${RARE_SYMBOLS.OPENING_TAG}${id}${RARE_SYMBOLS.CLOSING_TAG}`
684
+ };
685
+ this._citations.set(id, citation);
686
+ return citation;
687
+ }
688
+ /**
689
+ * Extracts citations from the provided content and cleans the content of citation tags.
690
+ * Non-found citations are replaced with a special "Not Found" citation.
691
+ * @param content The string content containing citation tags.
692
+ * @returns An object containing the cleaned content and an array of found citations.
693
+ */
694
+ extractCitations(content, replace) {
695
+ const citations = [];
696
+ const notFoundCitation = {
697
+ id: -1,
698
+ source: "Not Found",
699
+ tag: ""
700
+ };
701
+ const regex = new RegExp(`${RARE_SYMBOLS.OPENING_TAG}([\\d|\\w|\\s|,]{0,})${RARE_SYMBOLS.CLOSING_TAG}`, "ig");
702
+ let match;
703
+ const offsets = [];
704
+ while ((match = regex.exec(content)) !== null) {
705
+ const offset = match.index;
706
+ const length = match[0].length;
707
+ offsets.push({
708
+ start: offset,
709
+ length
710
+ });
711
+ const multi = (match[1] ?? "").split(/\D/g).map((s) => s.trim()).filter(Boolean).map((s) => parseInt(s, 10)).filter((s) => !isNaN(s) && s >= 0);
712
+ for (const citationId of multi) {
713
+ const citation = this._citations.get(citationId);
714
+ if (citation) citations.push({
715
+ ...citation,
716
+ offset
717
+ });
718
+ else citations.push({
719
+ ...notFoundCitation,
720
+ offset
721
+ });
722
+ }
723
+ }
724
+ const entries = offsets.map((o) => ({
725
+ start: o.start,
726
+ length: o.length,
727
+ citations: citations.filter((x) => x.offset === o.start && x.id !== -1)
728
+ })).sort((a, b) => a.start - b.start);
729
+ let result = "";
730
+ let cursor = 0;
731
+ for (const { start, length, citations } of entries) {
732
+ result += content.slice(cursor, start);
733
+ const replacement = citations.map((citation) => replace ? replace(citation) : "").join("");
734
+ result += replacement;
735
+ cursor = start + length;
736
+ }
737
+ result += content.slice(cursor);
738
+ return {
739
+ cleaned: result,
740
+ citations
741
+ };
742
+ }
743
+ /**
744
+ * Strips citation tags from the provided content.
745
+ * @param content The string content containing citation tags.
746
+ * @returns The cleaned content without citation tags.
747
+ */
748
+ static stripCitationTags(content) {
749
+ const regex = new RegExp(`${RARE_SYMBOLS.OPENING_TAG}([\\d|\\w|\\s|,]{0,})${RARE_SYMBOLS.CLOSING_TAG}?`, "g");
750
+ return content.replace(regex, "");
751
+ }
752
+ /**
753
+ * Removes citations from a deeply nested plain object and returns a new object with citations removed.
754
+ * @param obj The plain object to process.
755
+ * @returns A tuple containing the new object and an array of extracted citations with paths.
756
+ */
757
+ removeCitationsFromObject(obj) {
758
+ const result = [];
759
+ const processObject = (current, path) => {
760
+ if (typeof current === "string") {
761
+ const extraction = this.extractCitations(current);
762
+ if (extraction.citations.length > 0) result.push(...extraction.citations.map((citation) => ({
763
+ path,
764
+ citation
765
+ })));
766
+ return extraction.cleaned;
767
+ } else if (typeof current === "object" && current !== null) {
768
+ const newObject = Array.isArray(current) ? [] : {};
769
+ for (const key of Object.keys(current)) newObject[key] = processObject(current[key], `${path}.${key}`);
770
+ return newObject;
771
+ }
772
+ return current;
773
+ };
774
+ return [processObject(obj, "root"), result];
775
+ }
776
+ /**
777
+ * Re-adds citations to the cleaned content based on their offsets.
778
+ * @param cleaned The cleaned string without citation tags.
779
+ * @param citations The array of citations with offsets.
780
+ * @returns The string with citation tags re-added.
781
+ */
782
+ reAddCitations(cleaned, citations) {
783
+ let content = cleaned;
784
+ citations.sort((a, b) => (a.offset ?? 0) - (b.offset ?? 0));
785
+ const adjustment = 0;
786
+ for (const citation of citations) if (citation.offset != null) {
787
+ const position = citation.offset + adjustment;
788
+ content = content.slice(0, position) + citation.tag + content.slice(position);
789
+ }
790
+ return content;
791
+ }
792
+ };
793
+ //#endregion
794
+ //#region src/component.default.ts
795
+ const Button = new require_component.Component({
796
+ type: "leaf",
797
+ description: "A button component that can perform actions when clicked",
798
+ name: "Button",
799
+ aliases: ["btn"],
800
+ generation: {
801
+ usage: "Attach quick actions to a message, e.g. postback choices or a URL to open.",
802
+ examples: [{ props: {
803
+ action: "postback",
804
+ label: "Buy",
805
+ value: "buy_product"
806
+ } }]
807
+ },
808
+ leaf: { props: _bpinternal_zui.z.object({
809
+ action: _bpinternal_zui.z.enum([
810
+ "say",
811
+ "url",
812
+ "postback"
813
+ ]).default("say").describe("The action to perform when the button is clicked. Can be \"say\", \"url\", or \"postback\""),
814
+ label: _bpinternal_zui.z.string().describe("The text displayed on the button (min 1 character, max 250 characters)"),
815
+ value: _bpinternal_zui.z.string().optional().describe("The postback value to send when the button is clicked. Required if action is \"postback\""),
816
+ url: _bpinternal_zui.z.string().optional().describe("The URL to open when the button is clicked. Required if action is \"url\"")
817
+ }) }
768
818
  });
769
- var File = new (0, _chunkI56MPOVGcjs.Component)({
770
- type: "leaf",
771
- name: "File",
772
- description: "Sends a downloadable file to the user.",
773
- aliases: [],
774
- generation: {
775
- examples: [{ props: { url: "https://example.com/report.pdf", name: "Report.pdf" } }]
776
- },
777
- leaf: {
778
- props: _zui.z.object({
779
- url: _zui.z.string().describe("The URL of the file (must be valid)"),
780
- name: _zui.z.string().optional().describe("The display name of the file")
781
- })
782
- }
819
+ const Image = new require_component.Component({
820
+ type: "leaf",
821
+ name: "Image",
822
+ description: "Displays an image from a URL.",
823
+ aliases: [],
824
+ generation: { examples: [{ props: {
825
+ url: "https://example.com/photo.jpg",
826
+ alt: "Example image"
827
+ } }] },
828
+ leaf: { props: _bpinternal_zui.z.object({
829
+ url: _bpinternal_zui.z.string().describe("The URL of the image (must be valid)"),
830
+ alt: _bpinternal_zui.z.string().optional().describe("Alternative text describing the image")
831
+ }) }
783
832
  });
784
- var Video = new (0, _chunkI56MPOVGcjs.Component)({
785
- type: "leaf",
786
- name: "Video",
787
- description: "Embeds a video from a URL.",
788
- aliases: [],
789
- generation: {
790
- examples: [{ props: { url: "https://example.com/intro.mp4", title: "Welcome" } }]
791
- },
792
- leaf: {
793
- props: _zui.z.object({
794
- url: _zui.z.string().describe("The URL of the video (must be valid)"),
795
- title: _zui.z.string().optional().describe("Title for the video")
796
- })
797
- }
833
+ const File = new require_component.Component({
834
+ type: "leaf",
835
+ name: "File",
836
+ description: "Sends a downloadable file to the user.",
837
+ aliases: [],
838
+ generation: { examples: [{ props: {
839
+ url: "https://example.com/report.pdf",
840
+ name: "Report.pdf"
841
+ } }] },
842
+ leaf: { props: _bpinternal_zui.z.object({
843
+ url: _bpinternal_zui.z.string().describe("The URL of the file (must be valid)"),
844
+ name: _bpinternal_zui.z.string().optional().describe("The display name of the file")
845
+ }) }
798
846
  });
799
- var Audio = new (0, _chunkI56MPOVGcjs.Component)({
800
- type: "leaf",
801
- name: "Audio",
802
- description: "Plays an audio clip from a URL.",
803
- aliases: [],
804
- generation: {
805
- examples: [{ props: { url: "https://example.com/audio.mp3", title: "Sample" } }]
806
- },
807
- leaf: {
808
- props: _zui.z.object({
809
- url: _zui.z.string().describe("The URL of the audio clip (must be valid)"),
810
- title: _zui.z.string().optional().describe("Title for the audio clip")
811
- })
812
- }
847
+ const Video = new require_component.Component({
848
+ type: "leaf",
849
+ name: "Video",
850
+ description: "Embeds a video from a URL.",
851
+ aliases: [],
852
+ generation: { examples: [{ props: {
853
+ url: "https://example.com/intro.mp4",
854
+ title: "Welcome"
855
+ } }] },
856
+ leaf: { props: _bpinternal_zui.z.object({
857
+ url: _bpinternal_zui.z.string().describe("The URL of the video (must be valid)"),
858
+ title: _bpinternal_zui.z.string().optional().describe("Title for the video")
859
+ }) }
813
860
  });
814
- var Card = new (0, _chunkI56MPOVGcjs.Component)({
815
- type: "container",
816
- name: "Card",
817
- description: "A visual card component that can include an image and buttons.",
818
- aliases: [],
819
- generation: {
820
- examples: [{ props: { title: "Product Name", subtitle: "Limited offer" }, body: "Featured product of the week." }]
821
- },
822
- container: {
823
- props: _zui.z.object({
824
- title: _zui.z.string().min(1).max(250).describe("Title text (1\u2013250 characters)"),
825
- subtitle: _zui.z.string().optional().describe("Optional subtitle for the card")
826
- }),
827
- children: [
828
- {
829
- description: "Image (optional, max 1)",
830
- component: Image.definition
831
- },
832
- {
833
- description: "Button (optional, up to 5)",
834
- component: Button.definition
835
- }
836
- ]
837
- }
861
+ const Audio = new require_component.Component({
862
+ type: "leaf",
863
+ name: "Audio",
864
+ description: "Plays an audio clip from a URL.",
865
+ aliases: [],
866
+ generation: { examples: [{ props: {
867
+ url: "https://example.com/audio.mp3",
868
+ title: "Sample"
869
+ } }] },
870
+ leaf: { props: _bpinternal_zui.z.object({
871
+ url: _bpinternal_zui.z.string().describe("The URL of the audio clip (must be valid)"),
872
+ title: _bpinternal_zui.z.string().optional().describe("Title for the audio clip")
873
+ }) }
838
874
  });
839
- var Carousel = new (0, _chunkI56MPOVGcjs.Component)({
840
- type: "container",
841
- name: "Carousel",
842
- description: "A virtual container for displaying 1 to 10 Card components as a carousel.",
843
- aliases: [],
844
- container: {
845
- props: _zui.z.object({}),
846
- children: [
847
- {
848
- description: "Card component (required, 1\u201310 allowed)",
849
- component: Card.definition
850
- }
851
- ]
852
- }
875
+ const Card = new require_component.Component({
876
+ type: "container",
877
+ name: "Card",
878
+ description: "A visual card component that can include an image and buttons.",
879
+ aliases: [],
880
+ generation: { examples: [{
881
+ props: {
882
+ title: "Product Name",
883
+ subtitle: "Limited offer"
884
+ },
885
+ body: "Featured product of the week."
886
+ }] },
887
+ container: {
888
+ props: _bpinternal_zui.z.object({
889
+ title: _bpinternal_zui.z.string().min(1).max(250).describe("Title text (1–250 characters)"),
890
+ subtitle: _bpinternal_zui.z.string().optional().describe("Optional subtitle for the card")
891
+ }),
892
+ children: [{
893
+ description: "Image (optional, max 1)",
894
+ component: Image.definition
895
+ }, {
896
+ description: "Button (optional, up to 5)",
897
+ component: Button.definition
898
+ }]
899
+ }
853
900
  });
854
- var Text = new (0, _chunkI56MPOVGcjs.Component)({
855
- type: "default",
856
- name: "Message",
857
- aliases: ["Text", "Markdown"],
858
- description: "A Markdown-formatted text message. Long answers are written the same way: plain Markdown prose.",
859
- generation: {
860
- examples: [
861
- // A long-form example matters: models shown only short bodies have been
862
- // observed drifting into JSON-wrapping long replies ({"body": "..."})
863
- {
864
- body: `Great question! Deploying happens in three steps.
865
-
866
- First, connect your repository from the dashboard \u2014 we support GitHub and GitLab. Once connected, every push to your main branch triggers a build automatically.
901
+ const DefaultComponents = {
902
+ Button,
903
+ Image,
904
+ File,
905
+ Video,
906
+ Audio,
907
+ Card,
908
+ Carousel: new require_component.Component({
909
+ type: "container",
910
+ name: "Carousel",
911
+ description: "A virtual container for displaying 1 to 10 Card components as a carousel.",
912
+ aliases: [],
913
+ container: {
914
+ props: _bpinternal_zui.z.object({}),
915
+ children: [{
916
+ description: "Card component (required, 1–10 allowed)",
917
+ component: Card.definition
918
+ }]
919
+ }
920
+ }),
921
+ Text: new require_component.Component({
922
+ type: "default",
923
+ name: "Message",
924
+ aliases: ["Text", "Markdown"],
925
+ description: "A Markdown-formatted text message. Long answers are written the same way: plain Markdown prose.",
926
+ generation: { examples: [{ body: `Great question! Deploying happens in three steps.
927
+
928
+ First, connect your repository from the dashboard — we support GitHub and GitLab. Once connected, every push to your main branch triggers a build automatically.
867
929
 
868
930
  Then configure your build settings:
869
931
 
870
- - **Build command** \u2014 usually \`npm run build\`
871
- - **Output directory** \u2014 where the compiled assets end up
872
-
873
- Finally, hit **Deploy**. The first build takes a couple of minutes; subsequent ones are incremental and much faster. Want me to walk you through connecting your repository?`
874
- },
875
- { body: "**Hello**, welcome to our service!" }
876
- ]
877
- },
878
- default: {
879
- props: _zui.z.object({}),
880
- children: []
881
- }
882
- });
883
- var Speech = new (0, _chunkI56MPOVGcjs.Component)({
884
- type: "default",
885
- name: "Speech",
886
- aliases: ["speak", "spoken"],
887
- description: "A message spoken aloud to the user via text-to-speech.",
888
- body: {
889
- format: "text",
890
- description: 'Plain conversational prose only, written to be read aloud: no Markdown, no links or URLs, no emojis, no code, no bullet points, tables or headings. Write everything the way it should be pronounced \u2014 spell out numbers, dates, units and abbreviations (e.g. "June third at three thirty PM", not "06/03 @ 3:30pm").'
891
- },
892
- generation: {
893
- usage: "Use when the reply will be played back as audio (voice conversations).",
894
- examples: [
895
- { body: "Sure! Your order shipped this morning and should arrive on Tuesday, June third, around noon." }
896
- ]
897
- },
898
- default: {
899
- props: _zui.z.object({}),
900
- children: []
901
- }
902
- });
903
- var DefaultComponents = {
904
- Button,
905
- Image,
906
- File,
907
- Video,
908
- Audio,
909
- Card,
910
- Carousel,
911
- Text,
912
- Speech
932
+ - **Build command** — usually \`npm run build\`
933
+ - **Output directory** — where the compiled assets end up
934
+
935
+ Finally, hit **Deploy**. The first build takes a couple of minutes; subsequent ones are incremental and much faster. Want me to walk you through connecting your repository?` }, { body: "**Hello**, welcome to our service!" }] },
936
+ default: {
937
+ props: _bpinternal_zui.z.object({}),
938
+ children: []
939
+ }
940
+ }),
941
+ Speech: new require_component.Component({
942
+ type: "default",
943
+ name: "Speech",
944
+ aliases: ["speak", "spoken"],
945
+ description: "A message spoken aloud to the user via text-to-speech.",
946
+ body: {
947
+ format: "text",
948
+ description: "Plain conversational prose only, written to be read aloud: no Markdown, no links or URLs, no emojis, no code, no bullet points, tables or headings. Write everything the way it should be pronounced — spell out numbers, dates, units and abbreviations (e.g. \"June third at three thirty PM\", not \"06/03 @ 3:30pm\")."
949
+ },
950
+ generation: {
951
+ usage: "Use when the reply will be played back as audio (voice conversations).",
952
+ examples: [{ body: "Sure! Your order shipped this morning and should arrive on Tuesday, June third, around noon." }]
953
+ },
954
+ default: {
955
+ props: _bpinternal_zui.z.object({}),
956
+ children: []
957
+ }
958
+ })
913
959
  };
914
-
915
- // src/chat.ts
960
+ //#endregion
961
+ //#region src/chat.ts
962
+ /**
963
+ * Base class for implementing chat interfaces in LLMz agents.
964
+ *
965
+ * The Chat class provides the foundation for interactive conversational agents by defining
966
+ * how agents communicate with users. It manages the conversation transcript, available UI
967
+ * components, and message handling. This is the bridge between the agent's generated code
968
+ * and your user interface.
969
+ *
970
+ * ## Key Concepts
971
+ *
972
+ * **Handler Function**: The core method that receives agent messages (rendered components)
973
+ * and displays them to the user. This is called every time the agent wants to communicate.
974
+ *
975
+ * **Transcript**: An up-to-date conversation history that is evaluated at each iteration.
976
+ * The transcript must reflect the complete conversation state as the agent uses it to
977
+ * understand context and generate appropriate responses.
978
+ *
979
+ * **Components**: The UI elements available to the agent for creating rich interactive
980
+ * experiences (text, buttons, images, cards, etc.).
981
+ *
982
+ * ## Implementation Requirements
983
+ *
984
+ * To create a functional chat interface, you must:
985
+ * 1. Implement the MessageHandler to display agent messages to users
986
+ * 2. Maintain an accurate transcript of the conversation
987
+ * 3. Provide the available UI components (typically includes DefaultComponents)
988
+ * 4. Optional: Override onExecutionDone() to handle execution completion
989
+ *
990
+ * ## Basic Implementation
991
+ *
992
+ * ```typescript
993
+ * import { Chat, DefaultComponents, isComponent } from 'llmz'
994
+ *
995
+ * class MyChat extends Chat {
996
+ * private messages: Array<{role: 'user' | 'assistant', content: string}> = []
997
+ *
998
+ * constructor() {
999
+ * super({
1000
+ * // Handle agent messages - this is called for every agent output
1001
+ * handler: async (input) => {
1002
+ * if (isComponent(input, DefaultComponents.Text)) {
1003
+ * const text = input.children.join('')
1004
+ * console.log('Agent:', text)
1005
+ * this.messages.push({ role: 'assistant', content: text })
1006
+ * } else if (isComponent(input, DefaultComponents.Button)) {
1007
+ * console.log('Button:', input.props.label)
1008
+ * }
1009
+ * },
1010
+ *
1011
+ * // Provide available components - agent can use these in generated code
1012
+ * components: [DefaultComponents.Text, DefaultComponents.Button],
1013
+ *
1014
+ * // Return current transcript - evaluated at each iteration
1015
+ * transcript: () => this.messages,
1016
+ * })
1017
+ * }
1018
+ *
1019
+ * // Add user message to transcript
1020
+ * addUserMessage(content: string) {
1021
+ * this.messages.push({ role: 'user', content })
1022
+ * }
1023
+ * }
1024
+ *
1025
+ * // Usage
1026
+ * const chat = new MyChat()
1027
+ * chat.addUserMessage('Hello!')
1028
+ *
1029
+ * const result = await execute({
1030
+ * instructions: 'You are a helpful assistant',
1031
+ * chat, // Enable chat mode
1032
+ * client,
1033
+ * })
1034
+ * ```
1035
+ *
1036
+ * ## Advanced Implementation (CLIChat Example)
1037
+ *
1038
+ * ```typescript
1039
+ * import { Chat, DefaultComponents, ListenExit } from 'llmz'
1040
+ *
1041
+ * class CLIChat extends Chat {
1042
+ * public transcript: Array<{role: 'user' | 'assistant', content: string}> = []
1043
+ * private buttons: string[] = []
1044
+ * public result?: ExecutionResult
1045
+ *
1046
+ * constructor() {
1047
+ * super({
1048
+ * // Dynamic component list with custom renderers
1049
+ * components: () => [
1050
+ * DefaultComponents.Text,
1051
+ * DefaultComponents.Button,
1052
+ * ...this.customComponents
1053
+ * ],
1054
+ *
1055
+ * // Dynamic transcript access
1056
+ * transcript: () => this.transcript,
1057
+ *
1058
+ * // Sophisticated message handling
1059
+ * handler: async (input) => {
1060
+ * if (isComponent(input, DefaultComponents.Text)) {
1061
+ * const text = input.children.join('')
1062
+ * console.log('🤖 Agent:', text)
1063
+ * this.transcript.push({ role: 'assistant', content: text })
1064
+ * } else if (isComponent(input, DefaultComponents.Button)) {
1065
+ * this.buttons.push(input.props.label)
1066
+ * }
1067
+ * },
1068
+ * })
1069
+ * }
1070
+ *
1071
+ * // Handle execution completion
1072
+ * onExecutionDone(result: ExecutionResult) {
1073
+ * this.result = result
1074
+ * }
1075
+ *
1076
+ * // Check if agent is waiting for user input
1077
+ * isWaitingForInput(): boolean {
1078
+ * return this.result?.is(ListenExit) ?? false
1079
+ * }
1080
+ *
1081
+ * // Conversation loop
1082
+ * async iterate(): Promise<boolean> {
1083
+ * if (this.isWaitingForInput()) {
1084
+ * const userInput = await this.promptUser()
1085
+ * this.transcript.push({ role: 'user', content: userInput })
1086
+ * return true // Continue conversation
1087
+ * }
1088
+ * return false // End conversation
1089
+ * }
1090
+ * }
1091
+ * ```
1092
+ *
1093
+ * ## Component System
1094
+ *
1095
+ * The agent generates JSX code using available components:
1096
+ *
1097
+ * ```typescript
1098
+ * // Agent generates this TSX code:
1099
+ * yield <Text>Welcome! Choose an option:</Text>
1100
+ * yield <Button action="postback" label="Get Help" value="help" />
1101
+ * yield <Button action="postback" label="Contact Sales" value="sales" />
1102
+ *
1103
+ * // Your handler receives these as RenderedComponent objects
1104
+ * ```
1105
+ *
1106
+ * ## Transcript Management
1107
+ *
1108
+ * The transcript is critical for agent context and must be kept up-to-date:
1109
+ *
1110
+ * ```typescript
1111
+ * // ❌ Bad - static transcript
1112
+ * transcript: [{ role: 'user', content: 'Hello' }]
1113
+ *
1114
+ * // ✅ Good - dynamic transcript that reflects current state
1115
+ * transcript: () => this.messages
1116
+ *
1117
+ * // The transcript is evaluated at each iteration, so the agent
1118
+ * // always sees the current conversation state
1119
+ * ```
1120
+ *
1121
+ * ## Custom Components
1122
+ *
1123
+ * Extend the UI with custom components for your specific use case:
1124
+ *
1125
+ * ```typescript
1126
+ * import { Component } from 'llmz'
1127
+ *
1128
+ * const ProductCard = new Component({
1129
+ * type: 'leaf',
1130
+ * name: 'ProductCard',
1131
+ * leaf: {
1132
+ * props: z.object({
1133
+ * name: z.string(),
1134
+ * price: z.number(),
1135
+ * imageUrl: z.string(),
1136
+ * })
1137
+ * }
1138
+ * })
1139
+ *
1140
+ * class ShoppingChat extends Chat {
1141
+ * constructor() {
1142
+ * super({
1143
+ * components: [
1144
+ * ...DefaultComponents,
1145
+ * ProductCard, // Add custom component
1146
+ * ],
1147
+ * handler: async (input) => {
1148
+ * if (isComponent(input, ProductCard)) {
1149
+ * // Handle custom component rendering
1150
+ * this.renderProduct(input.props)
1151
+ * }
1152
+ * // ... handle other components
1153
+ * },
1154
+ * })
1155
+ * }
1156
+ * }
1157
+ * ```
1158
+ *
1159
+ * @see {@link DefaultComponents} For standard UI components
1160
+ * @see {@link https://github.com/botpress/botpress/blob/master/packages/llmz/examples/utils/cli-chat.ts} Complete CLIChat implementation
1161
+ */
916
1162
  var Chat = class {
917
-
918
-
919
-
920
-
921
- /**
922
- * Creates a new Chat instance.
923
- *
924
- * @param props - Chat configuration
925
- * @param props.handler - Function to handle agent messages (called for every agent output)
926
- * @param props.components - Available UI components (static array or dynamic function)
927
- * @param props.transcript - Conversation history (static array or dynamic function, defaults to empty)
928
- *
929
- * @example
930
- * ```typescript
931
- * // Basic chat with static configuration
932
- * const chat = new Chat({
933
- * handler: async (input) => {
934
- * if (isComponent(input, DefaultComponents.Text)) {
935
- * console.log('Agent:', input.children.join(''))
936
- * }
937
- * },
938
- * components: [DefaultComponents.Text, DefaultComponents.Button],
939
- * transcript: [
940
- * { role: 'user', content: 'Hello', timestamp: Date.now() }
941
- * ],
942
- * })
943
- * ```
944
- *
945
- * @example
946
- * ```typescript
947
- * // Dynamic chat with functions for real-time updates
948
- * class MyChat extends Chat {
949
- * private messages: Transcript.Message[] = []
950
- *
951
- * constructor() {
952
- * super({
953
- * handler: (input) => this.handleMessage(input),
954
- *
955
- * // Dynamic components - can change during execution
956
- * components: () => [
957
- * DefaultComponents.Text,
958
- * DefaultComponents.Button,
959
- * ...this.getCustomComponents()
960
- * ],
961
- *
962
- * // Dynamic transcript - always reflects current state
963
- * transcript: () => this.messages,
964
- * })
965
- * }
966
- * }
967
- * ```
968
- */
969
- constructor(props) {
970
- this.handler = props.handler;
971
- this.onMessageDelta = props.onMessageDelta;
972
- this.components = props.components;
973
- this.transcript = props.transcript || [];
974
- }
975
- /**
976
- * Called when an execution cycle completes, regardless of the outcome.
977
- *
978
- * Override this method to handle execution results, manage conversation flow,
979
- * or perform cleanup tasks. This is called after each `execute()` call completes,
980
- * whether it succeeds, fails, or is interrupted.
981
- *
982
- * @param result - The execution result containing status, iterations, and exit information
983
- *
984
- * @example
985
- * ```typescript
986
- * class MyChat extends Chat {
987
- * public result?: ExecutionResult
988
- *
989
- * onExecutionDone(result: ExecutionResult) {
990
- * // Store result for conversation flow control
991
- * this.result = result
992
- *
993
- * // Handle different result types
994
- * if (result.isSuccess()) {
995
- * console.log('✅ Execution completed successfully')
996
- * console.log('Exit:', result.output.exit_name)
997
- * } else if (result.isError()) {
998
- * console.error('❌ Execution failed:', result.output.error)
999
- * } else if (result.isInterrupted()) {
1000
- * console.log('⏸️ Execution interrupted (partial result)')
1001
- * }
1002
- * }
1003
- *
1004
- * // Use stored result for conversation flow
1005
- * isWaitingForInput(): boolean {
1006
- * return this.result?.is(ListenExit) ?? false
1007
- * }
1008
- * }
1009
- * ```
1010
- *
1011
- * @example
1012
- * ```typescript
1013
- * // CLIChat implementation example
1014
- * class CLIChat extends Chat {
1015
- * public status?: IterationStatus
1016
- * public result?: ExecutionResult
1017
- *
1018
- * onExecutionDone(result: ExecutionResult) {
1019
- * this.result = result
1020
- * this.status = result.iterations.at(-1)?.status
1021
- * }
1022
- *
1023
- * // Check if agent exited with specific exit type
1024
- * hasExitedWith<R>(exit: Exit<R>): boolean {
1025
- * return this.status?.type === 'exit_success' &&
1026
- * this.status.exit_success.exit_name === exit.name
1027
- * }
1028
- * }
1029
- * ```
1030
- */
1031
- onExecutionDone(_result) {
1032
- }
1163
+ handler;
1164
+ onMessageDelta;
1165
+ transcript;
1166
+ components;
1167
+ /**
1168
+ * Creates a new Chat instance.
1169
+ *
1170
+ * @param props - Chat configuration
1171
+ * @param props.handler - Function to handle agent messages (called for every agent output)
1172
+ * @param props.components - Available UI components (static array or dynamic function)
1173
+ * @param props.transcript - Conversation history (static array or dynamic function, defaults to empty)
1174
+ *
1175
+ * @example
1176
+ * ```typescript
1177
+ * // Basic chat with static configuration
1178
+ * const chat = new Chat({
1179
+ * handler: async (input) => {
1180
+ * if (isComponent(input, DefaultComponents.Text)) {
1181
+ * console.log('Agent:', input.children.join(''))
1182
+ * }
1183
+ * },
1184
+ * components: [DefaultComponents.Text, DefaultComponents.Button],
1185
+ * transcript: [
1186
+ * { role: 'user', content: 'Hello', timestamp: Date.now() }
1187
+ * ],
1188
+ * })
1189
+ * ```
1190
+ *
1191
+ * @example
1192
+ * ```typescript
1193
+ * // Dynamic chat with functions for real-time updates
1194
+ * class MyChat extends Chat {
1195
+ * private messages: Transcript.Message[] = []
1196
+ *
1197
+ * constructor() {
1198
+ * super({
1199
+ * handler: (input) => this.handleMessage(input),
1200
+ *
1201
+ * // Dynamic components - can change during execution
1202
+ * components: () => [
1203
+ * DefaultComponents.Text,
1204
+ * DefaultComponents.Button,
1205
+ * ...this.getCustomComponents()
1206
+ * ],
1207
+ *
1208
+ * // Dynamic transcript - always reflects current state
1209
+ * transcript: () => this.messages,
1210
+ * })
1211
+ * }
1212
+ * }
1213
+ * ```
1214
+ */
1215
+ constructor(props) {
1216
+ this.handler = props.handler;
1217
+ this.onMessageDelta = props.onMessageDelta;
1218
+ this.components = props.components;
1219
+ this.transcript = props.transcript || [];
1220
+ }
1221
+ /**
1222
+ * Called when an execution cycle completes, regardless of the outcome.
1223
+ *
1224
+ * Override this method to handle execution results, manage conversation flow,
1225
+ * or perform cleanup tasks. This is called after each `execute()` call completes,
1226
+ * whether it succeeds, fails, or is interrupted.
1227
+ *
1228
+ * @param result - The execution result containing status, iterations, and exit information
1229
+ *
1230
+ * @example
1231
+ * ```typescript
1232
+ * class MyChat extends Chat {
1233
+ * public result?: ExecutionResult
1234
+ *
1235
+ * onExecutionDone(result: ExecutionResult) {
1236
+ * // Store result for conversation flow control
1237
+ * this.result = result
1238
+ *
1239
+ * // Handle different result types
1240
+ * if (result.isSuccess()) {
1241
+ * console.log('✅ Execution completed successfully')
1242
+ * console.log('Exit:', result.output.exit_name)
1243
+ * } else if (result.isError()) {
1244
+ * console.error('❌ Execution failed:', result.output.error)
1245
+ * } else if (result.isInterrupted()) {
1246
+ * console.log('⏸️ Execution interrupted (partial result)')
1247
+ * }
1248
+ * }
1249
+ *
1250
+ * // Use stored result for conversation flow
1251
+ * isWaitingForInput(): boolean {
1252
+ * return this.result?.is(ListenExit) ?? false
1253
+ * }
1254
+ * }
1255
+ * ```
1256
+ *
1257
+ * @example
1258
+ * ```typescript
1259
+ * // CLIChat implementation example
1260
+ * class CLIChat extends Chat {
1261
+ * public status?: IterationStatus
1262
+ * public result?: ExecutionResult
1263
+ *
1264
+ * onExecutionDone(result: ExecutionResult) {
1265
+ * this.result = result
1266
+ * this.status = result.iterations.at(-1)?.status
1267
+ * }
1268
+ *
1269
+ * // Check if agent exited with specific exit type
1270
+ * hasExitedWith<R>(exit: Exit<R>): boolean {
1271
+ * return this.status?.type === 'exit_success' &&
1272
+ * this.status.exit_success.exit_name === exit.name
1273
+ * }
1274
+ * }
1275
+ * ```
1276
+ */
1277
+ onExecutionDone(_result) {}
1033
1278
  };
1034
-
1035
- // src/message-stream/replayable.ts
1036
- var ReplayableAsyncIterable = (_class2 = class {
1037
-
1038
- __init3() {this._chunks = []}
1039
- __init4() {this._done = false}
1040
- __init5() {this._failed = false}
1041
-
1042
- __init6() {this._lock = Promise.resolve()}
1043
- constructor(source) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);
1044
- this._source = source[Symbol.asyncIterator]();
1045
- }
1046
- /** True once the underlying source has been fully consumed (or has failed). */
1047
- get done() {
1048
- return this._done;
1049
- }
1050
- /** The chunks pulled from the source so far. */
1051
- get chunks() {
1052
- return [...this._chunks];
1053
- }
1054
- async *[Symbol.asyncIterator]() {
1055
- let index = 0;
1056
- while (true) {
1057
- if (index < this._chunks.length) {
1058
- yield this._chunks[index++];
1059
- } else if (this._failed) {
1060
- throw this._error;
1061
- } else if (this._done) {
1062
- return;
1063
- } else {
1064
- await this._pull();
1065
- }
1066
- }
1067
- }
1068
- /** Consumes the entire source and returns all chunks. */
1069
- async collect() {
1070
- for await (const _ of this) {
1071
- }
1072
- return this.chunks;
1073
- }
1074
- _pull() {
1075
- const next = this._lock.then(async () => {
1076
- if (this._done) {
1077
- return;
1078
- }
1079
- let result;
1080
- try {
1081
- result = await this._source.next();
1082
- } catch (thrown) {
1083
- this._done = true;
1084
- this._failed = true;
1085
- this._error = thrown;
1086
- throw thrown;
1087
- }
1088
- if (result.done) {
1089
- this._done = true;
1090
- } else {
1091
- this._chunks.push(result.value);
1092
- }
1093
- });
1094
- this._lock = next.catch(() => {
1095
- });
1096
- return next;
1097
- }
1098
- }, _class2);
1099
- var collectText = async (iterable) => {
1100
- let text = "";
1101
- for await (const chunk of iterable) {
1102
- text += chunk;
1103
- }
1104
- return text;
1279
+ //#endregion
1280
+ //#region src/message-stream/replayable.ts
1281
+ /**
1282
+ * Wraps an async iterable so it can be iterated multiple times: chunks pulled
1283
+ * from the source are cached, and every iteration replays the cache before
1284
+ * pulling new chunks. Concurrent iterations are safe — pulls on the underlying
1285
+ * source are serialized. If the source fails, the failure is cached too:
1286
+ * every iteration replays the chunks received before the failure, then
1287
+ * rethrows the source error.
1288
+ */
1289
+ var ReplayableAsyncIterable = class {
1290
+ _source;
1291
+ _chunks = [];
1292
+ _done = false;
1293
+ _failed = false;
1294
+ _error;
1295
+ _lock = Promise.resolve();
1296
+ constructor(source) {
1297
+ this._source = source[Symbol.asyncIterator]();
1298
+ }
1299
+ /** True once the underlying source has been fully consumed (or has failed). */
1300
+ get done() {
1301
+ return this._done;
1302
+ }
1303
+ /** The chunks pulled from the source so far. */
1304
+ get chunks() {
1305
+ return [...this._chunks];
1306
+ }
1307
+ async *[Symbol.asyncIterator]() {
1308
+ let index = 0;
1309
+ while (true) if (index < this._chunks.length) yield this._chunks[index++];
1310
+ else if (this._failed) throw this._error;
1311
+ else if (this._done) return;
1312
+ else await this._pull();
1313
+ }
1314
+ /** Consumes the entire source and returns all chunks. */
1315
+ async collect() {
1316
+ for await (const _ of this);
1317
+ return this.chunks;
1318
+ }
1319
+ _pull() {
1320
+ const next = this._lock.then(async () => {
1321
+ if (this._done) return;
1322
+ let result;
1323
+ try {
1324
+ result = await this._source.next();
1325
+ } catch (thrown) {
1326
+ this._done = true;
1327
+ this._failed = true;
1328
+ this._error = thrown;
1329
+ throw thrown;
1330
+ }
1331
+ if (result.done) this._done = true;
1332
+ else this._chunks.push(result.value);
1333
+ });
1334
+ this._lock = next.catch(() => {});
1335
+ return next;
1336
+ }
1105
1337
  };
1106
-
1107
- // src/message-stream/stream.ts
1338
+ /** Drains a string iterable into a single string. */
1339
+ const collectText = async (iterable) => {
1340
+ let text = "";
1341
+ for await (const chunk of iterable) text += chunk;
1342
+ return text;
1343
+ };
1344
+ //#endregion
1345
+ //#region src/message-stream/stream.ts
1108
1346
  var BaseResponse = class {
1109
- constructor(action, item) {
1110
- this.action = action;
1111
- this.item = item;
1112
- }
1113
- get diagnostics() {
1114
- return this.item.diagnostics;
1115
- }
1347
+ action;
1348
+ item;
1349
+ constructor(action, item) {
1350
+ this.action = action;
1351
+ this.item = item;
1352
+ }
1353
+ get diagnostics() {
1354
+ return this.item.diagnostics;
1355
+ }
1116
1356
  };
1357
+ /** `■send=<component> { props? }` followed by an optional streaming body. */
1117
1358
  var SendResponse = class extends BaseResponse {
1118
- constructor(item, content) {
1119
- super("send", item);
1120
- this.content = content;
1121
- }
1122
- get component() {
1123
- return this.item.name;
1124
- }
1125
- get props() {
1126
- return this.item.props;
1127
- }
1128
- static formatToText(component, props, body) {
1129
- const header = `${_chunkKTDBAJBBcjs.MARKER}send=${component}${props && Object.keys(props).length ? ` ${JSON.stringify(props)}` : ""}`;
1130
- return body ? `${header}
1131
- ${body}` : header;
1132
- }
1359
+ content;
1360
+ constructor(item, content) {
1361
+ super("send", item);
1362
+ this.content = content;
1363
+ }
1364
+ get component() {
1365
+ return this.item.name;
1366
+ }
1367
+ get props() {
1368
+ return this.item.props;
1369
+ }
1370
+ static formatToText(component, props, body) {
1371
+ const header = `■send=${component}${props && Object.keys(props).length ? ` ${JSON.stringify(props)}` : ""}`;
1372
+ return body ? `${header}\n${body}` : header;
1373
+ }
1133
1374
  };
1375
+ /** `■run` followed by streaming code. */
1134
1376
  var RunResponse = class extends BaseResponse {
1135
- constructor(item, code) {
1136
- super("run", item);
1137
- this.code = code;
1138
- }
1139
- static formatToText(code) {
1140
- return `${_chunkKTDBAJBBcjs.MARKER}run
1141
- ${code}`;
1142
- }
1377
+ code;
1378
+ constructor(item, code) {
1379
+ super("run", item);
1380
+ this.code = code;
1381
+ }
1382
+ static formatToText(code) {
1383
+ return `■run\n${code}`;
1384
+ }
1143
1385
  };
1386
+ /** `■next=<name> { props? }` — hands control to an exit (e.g. listen) with optional props. */
1144
1387
  var NextResponse = class extends BaseResponse {
1145
- constructor(item) {
1146
- super("next", item);
1147
- }
1148
- get name() {
1149
- return this.item.name;
1150
- }
1151
- get props() {
1152
- return this.item.props;
1153
- }
1154
- static formatToText(name, props) {
1155
- return `${_chunkKTDBAJBBcjs.MARKER}next=${name}${props && Object.keys(props).length ? ` ${JSON.stringify(props)}` : ""}`;
1156
- }
1388
+ constructor(item) {
1389
+ super("next", item);
1390
+ }
1391
+ get name() {
1392
+ return this.item.name;
1393
+ }
1394
+ get props() {
1395
+ return this.item.props;
1396
+ }
1397
+ static formatToText(name, props) {
1398
+ return `■next=${name}${props && Object.keys(props).length ? ` ${JSON.stringify(props)}` : ""}`;
1399
+ }
1157
1400
  };
1158
- var EventPump = (_class3 = class {
1159
-
1160
-
1161
- __init7() {this._queue = []}
1162
- __init8() {this._sourceDone = false}
1163
- __init9() {this._lock = Promise.resolve()}
1164
- constructor(stream, parser) {;_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);
1165
- this._iterator = stream[Symbol.asyncIterator]();
1166
- this._parser = parser;
1167
- }
1168
- next() {
1169
- const next = this._lock.then(() => this._next());
1170
- this._lock = next.catch(() => {
1171
- });
1172
- return next;
1173
- }
1174
- unshift(event) {
1175
- this._queue.unshift(event);
1176
- }
1177
- async _next() {
1178
- while (this._queue.length === 0) {
1179
- if (this._sourceDone) {
1180
- return void 0;
1181
- }
1182
- let result;
1183
- try {
1184
- result = await this._iterator.next();
1185
- } catch (e) {
1186
- this._sourceDone = true;
1187
- this._queue.push(...this._parser.finish("interrupted"));
1188
- continue;
1189
- }
1190
- if (result.done) {
1191
- this._sourceDone = true;
1192
- this._queue.push(...this._parser.finish());
1193
- } else {
1194
- this._queue.push(...this._parser.push(result.value));
1195
- }
1196
- }
1197
- return this._queue.shift();
1198
- }
1199
- }, _class3);
1401
+ /**
1402
+ * Pulls transport chunks through the parser on demand and hands out events one
1403
+ * at a time. Shared by the main response loop and by body streams; pulls are
1404
+ * serialized so interleaved consumers cannot race the source iterator.
1405
+ */
1406
+ var EventPump = class {
1407
+ _iterator;
1408
+ _parser;
1409
+ _queue = [];
1410
+ _sourceDone = false;
1411
+ _lock = Promise.resolve();
1412
+ constructor(stream, parser) {
1413
+ this._iterator = stream[Symbol.asyncIterator]();
1414
+ this._parser = parser;
1415
+ }
1416
+ next() {
1417
+ const next = this._lock.then(() => this._next());
1418
+ this._lock = next.catch(() => {});
1419
+ return next;
1420
+ }
1421
+ unshift(event) {
1422
+ this._queue.unshift(event);
1423
+ }
1424
+ async _next() {
1425
+ while (this._queue.length === 0) {
1426
+ if (this._sourceDone) return;
1427
+ let result;
1428
+ try {
1429
+ result = await this._iterator.next();
1430
+ } catch {
1431
+ this._sourceDone = true;
1432
+ this._queue.push(...this._parser.finish("interrupted"));
1433
+ continue;
1434
+ }
1435
+ if (result.done) {
1436
+ this._sourceDone = true;
1437
+ this._queue.push(...this._parser.finish());
1438
+ } else this._queue.push(...this._parser.push(result.value));
1439
+ }
1440
+ return this._queue.shift();
1441
+ }
1442
+ };
1443
+ /**
1444
+ * Parses a raw LLM text stream into typed responses.
1445
+ *
1446
+ * `send` and `run` responses are yielded as soon as their header is parsed —
1447
+ * while their body is still streaming — with the body exposed as a replayable
1448
+ * async iterable. `next` responses are yielded once complete.
1449
+ *
1450
+ * The body streams are pull-based: consuming them drives the underlying
1451
+ * transport. Requesting the next response first drains the previous body into
1452
+ * its replay cache, so it can always be read later.
1453
+ */
1200
1454
  function parseStream(stream, options) {
1201
- return parseResponses(stream, options);
1455
+ return parseResponses(stream, options);
1202
1456
  }
1457
+ /** Parses a complete text (convenience wrapper over {@link parseStream}). */
1203
1458
  function parseText(text, options) {
1204
- return parseResponses(
1205
- async function* () {
1206
- yield text;
1207
- }(),
1208
- options
1209
- );
1459
+ return parseResponses((async function* () {
1460
+ yield text;
1461
+ })(), options);
1210
1462
  }
1211
1463
  async function* parseResponses(stream, options) {
1212
- const parser = new (0, _chunkKTDBAJBBcjs.StreamingMessageParser)(options);
1213
- const pump = new EventPump(stream, parser);
1214
- let activeBody;
1215
- while (true) {
1216
- if (activeBody) {
1217
- await activeBody.collect();
1218
- activeBody = void 0;
1219
- }
1220
- const event = await pump.next();
1221
- if (!event) {
1222
- return;
1223
- }
1224
- if (event.type === "item-ready" && (event.item.kind === "send" || event.item.kind === "run")) {
1225
- const body = new ReplayableAsyncIterable(bodyStream(pump, event.item.id));
1226
- activeBody = body;
1227
- yield event.item.kind === "send" ? new SendResponse(event.item, body) : new RunResponse(event.item, body);
1228
- continue;
1229
- }
1230
- if (event.type === "item-complete" && event.item.kind === "next") {
1231
- yield new NextResponse(event.item);
1232
- continue;
1233
- }
1234
- }
1464
+ const pump = new EventPump(stream, new require_dual_modes.StreamingMessageParser(options));
1465
+ let activeBody;
1466
+ while (true) {
1467
+ if (activeBody) {
1468
+ await activeBody.collect();
1469
+ activeBody = void 0;
1470
+ }
1471
+ const event = await pump.next();
1472
+ if (!event) return;
1473
+ if (event.type === "item-ready" && (event.item.kind === "send" || event.item.kind === "run")) {
1474
+ const body = new ReplayableAsyncIterable(bodyStream(pump, event.item.id));
1475
+ activeBody = body;
1476
+ yield event.item.kind === "send" ? new SendResponse(event.item, body) : new RunResponse(event.item, body);
1477
+ continue;
1478
+ }
1479
+ if (event.type === "item-complete" && event.item.kind === "next") {
1480
+ yield new NextResponse(event.item);
1481
+ continue;
1482
+ }
1483
+ }
1235
1484
  }
1236
1485
  async function* bodyStream(pump, itemId) {
1237
- while (true) {
1238
- const event = await pump.next();
1239
- if (!event) {
1240
- return;
1241
- }
1242
- if (event.type === "body-delta" && event.itemId === itemId) {
1243
- yield event.delta;
1244
- continue;
1245
- }
1246
- if (event.type === "body-start" && event.itemId === itemId) {
1247
- continue;
1248
- }
1249
- if (event.type === "diagnostic") {
1250
- continue;
1251
- }
1252
- if (event.type === "item-complete" && event.item.id === itemId) {
1253
- return;
1254
- }
1255
- pump.unshift(event);
1256
- return;
1257
- }
1486
+ while (true) {
1487
+ const event = await pump.next();
1488
+ if (!event) return;
1489
+ if (event.type === "body-delta" && event.itemId === itemId) {
1490
+ yield event.delta;
1491
+ continue;
1492
+ }
1493
+ if (event.type === "body-start" && event.itemId === itemId) continue;
1494
+ if (event.type === "diagnostic") continue;
1495
+ if (event.type === "item-complete" && event.item.id === itemId) return;
1496
+ pump.unshift(event);
1497
+ return;
1498
+ }
1258
1499
  }
1259
-
1260
- // src/message-stream/registry.ts
1261
- var ComponentRegistry = (_class4 = class {
1262
- __init10() {this._definitions = /* @__PURE__ */ new Map()}
1263
- constructor(definitions = []) {;_class4.prototype.__init10.call(this);
1264
- for (const definition of definitions) {
1265
- this.register(definition);
1266
- }
1267
- }
1268
- register(definition) {
1269
- if (!_chunkKTDBAJBBcjs.NAME_REGEX.test(definition.name)) {
1270
- throw new Error(
1271
- `Invalid component name "${definition.name}". Component names must be lowercase ([a-z][a-z0-9_-]*).`
1272
- );
1273
- }
1274
- this._definitions.set(definition.name, definition);
1275
- }
1276
- unregister(name) {
1277
- this._definitions.delete(name);
1278
- }
1279
- has(name) {
1280
- return this._definitions.has(name);
1281
- }
1282
- get(name) {
1283
- return this._definitions.get(name);
1284
- }
1285
- list() {
1286
- return [...this._definitions.values()];
1287
- }
1288
- }, _class4);
1289
-
1290
- // src/message-stream/normalizer.ts
1291
-
1292
- var EMPTY_PROPS_SCHEMA = { type: "object", properties: {}, additionalProperties: false };
1293
- var normalizeComponentName = (name) => name.trim().toLowerCase();
1500
+ //#endregion
1501
+ //#region src/message-stream/registry.ts
1502
+ /**
1503
+ * Stores normalized component definitions. The registry (not the parser) is the
1504
+ * single source of truth for which components exist and how they are validated.
1505
+ */
1506
+ var ComponentRegistry = class {
1507
+ _definitions = /* @__PURE__ */ new Map();
1508
+ constructor(definitions = []) {
1509
+ for (const definition of definitions) this.register(definition);
1510
+ }
1511
+ register(definition) {
1512
+ if (!require_dual_modes.NAME_REGEX.test(definition.name)) throw new Error(`Invalid component name "${definition.name}". Component names must be lowercase ([a-z][a-z0-9_-]*).`);
1513
+ this._definitions.set(definition.name, definition);
1514
+ }
1515
+ unregister(name) {
1516
+ this._definitions.delete(name);
1517
+ }
1518
+ has(name) {
1519
+ return this._definitions.has(name);
1520
+ }
1521
+ get(name) {
1522
+ return this._definitions.get(name);
1523
+ }
1524
+ list() {
1525
+ return [...this._definitions.values()];
1526
+ }
1527
+ };
1528
+ //#endregion
1529
+ //#region src/message-stream/normalizer.ts
1530
+ const EMPTY_PROPS_SCHEMA = {
1531
+ type: "object",
1532
+ properties: {},
1533
+ additionalProperties: false
1534
+ };
1535
+ const normalizeComponentName = (name) => name.trim().toLowerCase();
1294
1536
  function normalizeComponentDefinition(definition) {
1295
- const name = normalizeComponentName(_nullishCoalesce(definition.name, () => ( "")));
1296
- if (!_chunkKTDBAJBBcjs.NAME_REGEX.test(name)) {
1297
- throw new Error(
1298
- `Invalid component name "${definition.name}". Component names must be lowercase ([a-z][a-z0-9_-]*).`
1299
- );
1300
- }
1301
- return {
1302
- name,
1303
- description: definition.description,
1304
- propsJsonSchema: normalizePropsSchema(definition.props, name),
1305
- body: definition.body ? {
1306
- format: definition.body.type,
1307
- description: definition.body.description,
1308
- required: _nullishCoalesce(definition.body.required, () => ( false))
1309
- } : void 0,
1310
- generation: definition.generation
1311
- };
1537
+ const name = normalizeComponentName(definition.name ?? "");
1538
+ if (!require_dual_modes.NAME_REGEX.test(name)) throw new Error(`Invalid component name "${definition.name}". Component names must be lowercase ([a-z][a-z0-9_-]*).`);
1539
+ return {
1540
+ name,
1541
+ description: definition.description,
1542
+ propsJsonSchema: normalizePropsSchema(definition.props, name),
1543
+ body: definition.body ? {
1544
+ format: definition.body.type,
1545
+ description: definition.body.description,
1546
+ required: definition.body.required ?? false
1547
+ } : void 0,
1548
+ generation: definition.generation
1549
+ };
1312
1550
  }
1313
1551
  function normalizePropsSchema(props, name) {
1314
- if (props === void 0) {
1315
- return EMPTY_PROPS_SCHEMA;
1316
- }
1317
- if (_chunkGOWPACSKcjs.isZuiSchema.call(void 0, props)) {
1318
- try {
1319
- return _zui.transforms.toJSONSchema(props);
1320
- } catch (e2) {
1321
- return _zui.transforms.toJSONSchemaLegacy(props);
1322
- }
1323
- }
1324
- if (_chunkGOWPACSKcjs.isJsonSchema.call(void 0, props)) {
1325
- return props;
1326
- }
1327
- throw new Error(
1328
- `Invalid props schema for "${name}". Expected a ZUI/Zod object schema or a JSON schema, but got type "${typeof props}".`
1329
- );
1552
+ if (props === void 0) return EMPTY_PROPS_SCHEMA;
1553
+ if (require_utils.isZuiSchema(props)) try {
1554
+ return _bpinternal_zui.transforms.toJSONSchema(props);
1555
+ } catch {
1556
+ return _bpinternal_zui.transforms.toJSONSchemaLegacy(props);
1557
+ }
1558
+ if (require_utils.isJsonSchema(props)) return props;
1559
+ throw new Error(`Invalid props schema for "${name}". Expected a ZUI/Zod object schema or a JSON schema, but got type "${typeof props}".`);
1330
1560
  }
1331
-
1332
- // src/message-stream/validator.ts
1561
+ //#endregion
1562
+ //#region src/message-stream/validator.ts
1563
+ /**
1564
+ * Validates a syntactically parsed `■send` item against the registered
1565
+ * component definitions. Validation is intentionally separate from parsing: a
1566
+ * validation failure never stops the stream, it only produces errors the caller
1567
+ * can turn into diagnostics or fallback rendering.
1568
+ */
1333
1569
  function validateComponent(item, registry) {
1334
- const definition = registry.get(item.name);
1335
- if (!definition) {
1336
- const registered = registry.list().map((d) => d.name).join(", ") || "(none)";
1337
- return {
1338
- valid: false,
1339
- props: item.props,
1340
- errors: [
1341
- {
1342
- code: "unknown-component",
1343
- message: `Unknown component "${item.name}". Registered components: ${registered}`
1344
- }
1345
- ]
1346
- };
1347
- }
1348
- const errors = [
1349
- ..._validateProps(item.props, definition),
1350
- ..._validateBody(item, definition)
1351
- ];
1352
- return { valid: errors.length === 0, props: item.props, errors };
1570
+ const definition = registry.get(item.name);
1571
+ if (!definition) {
1572
+ const registered = registry.list().map((d) => d.name).join(", ") || "(none)";
1573
+ return {
1574
+ valid: false,
1575
+ props: item.props,
1576
+ errors: [{
1577
+ code: "unknown-component",
1578
+ message: `Unknown component "${item.name}". Registered components: ${registered}`
1579
+ }]
1580
+ };
1581
+ }
1582
+ const errors = [..._validateProps(item.props, definition), ..._validateBody(item, definition)];
1583
+ return {
1584
+ valid: errors.length === 0,
1585
+ props: item.props,
1586
+ errors
1587
+ };
1353
1588
  }
1589
+ /** Validates a props object against a JSON schema (also used for `■next` exit props). */
1354
1590
  function validateProps(props, schema) {
1355
- const errors = [];
1356
- _checkValue(props, schema, "", errors);
1357
- return errors;
1591
+ const errors = [];
1592
+ _checkValue(props, schema, "", errors);
1593
+ return errors;
1358
1594
  }
1359
- var _validateProps = (props, definition) => validateProps(props, definition.propsJsonSchema);
1360
- var _validateBody = (item, definition) => {
1361
- var _a;
1362
- const hasBody = typeof item.body === "string" && item.body.length > 0;
1363
- if (hasBody && !definition.body) {
1364
- return [
1365
- {
1366
- code: "body-not-allowed",
1367
- message: `Component "${definition.name}" does not support a body`
1368
- }
1369
- ];
1370
- }
1371
- if (!hasBody && ((_a = definition.body) == null ? void 0 : _a.required)) {
1372
- return [
1373
- {
1374
- code: "missing-required-body",
1375
- message: `Component "${definition.name}" requires a body`
1376
- }
1377
- ];
1378
- }
1379
- return [];
1595
+ const _validateProps = (props, definition) => validateProps(props, definition.propsJsonSchema);
1596
+ const _validateBody = (item, definition) => {
1597
+ var _definition$body;
1598
+ const hasBody = typeof item.body === "string" && item.body.length > 0;
1599
+ if (hasBody && !definition.body) return [{
1600
+ code: "body-not-allowed",
1601
+ message: `Component "${definition.name}" does not support a body`
1602
+ }];
1603
+ if (!hasBody && ((_definition$body = definition.body) === null || _definition$body === void 0 ? void 0 : _definition$body.required)) return [{
1604
+ code: "missing-required-body",
1605
+ message: `Component "${definition.name}" requires a body`
1606
+ }];
1607
+ return [];
1380
1608
  };
1381
- var _typeOf = (value) => {
1382
- if (value === null)
1383
- return "null";
1384
- if (Array.isArray(value))
1385
- return "array";
1386
- return typeof value;
1609
+ const _typeOf = (value) => {
1610
+ if (value === null) return "null";
1611
+ if (Array.isArray(value)) return "array";
1612
+ return typeof value;
1387
1613
  };
1388
- var _matchesType = (value, type) => {
1389
- switch (type) {
1390
- case "string":
1391
- return typeof value === "string";
1392
- case "number":
1393
- return typeof value === "number";
1394
- case "integer":
1395
- return typeof value === "number" && Number.isInteger(value);
1396
- case "boolean":
1397
- return typeof value === "boolean";
1398
- case "null":
1399
- return value === null;
1400
- case "array":
1401
- return Array.isArray(value);
1402
- case "object":
1403
- return !!value && typeof value === "object" && !Array.isArray(value);
1404
- default:
1405
- return true;
1406
- }
1614
+ const _matchesType = (value, type) => {
1615
+ switch (type) {
1616
+ case "string": return typeof value === "string";
1617
+ case "number": return typeof value === "number";
1618
+ case "integer": return typeof value === "number" && Number.isInteger(value);
1619
+ case "boolean": return typeof value === "boolean";
1620
+ case "null": return value === null;
1621
+ case "array": return Array.isArray(value);
1622
+ case "object": return !!value && typeof value === "object" && !Array.isArray(value);
1623
+ default: return true;
1624
+ }
1407
1625
  };
1408
- var _isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
1409
- var _checkValue = (value, schema, path, errors) => {
1410
- if (schema === void 0 || typeof schema === "boolean" || typeof schema !== "object") {
1411
- return;
1412
- }
1413
- const label = path || "props";
1414
- const propError = (message) => {
1415
- errors.push({ code: "invalid-prop-value", message, path: path || void 0 });
1416
- };
1417
- if (schema.const !== void 0 && !_isEqual(value, schema.const)) {
1418
- propError(`Expected "${label}" to equal ${JSON.stringify(schema.const)}`);
1419
- return;
1420
- }
1421
- if (schema.enum && !schema.enum.some((allowed) => _isEqual(value, allowed))) {
1422
- propError(`Expected "${label}" to be one of: ${schema.enum.map((v) => JSON.stringify(v)).join(", ")}`);
1423
- return;
1424
- }
1425
- const variants = _nullishCoalesce(schema.anyOf, () => ( schema.oneOf));
1426
- if (variants == null ? void 0 : variants.length) {
1427
- const matchesAny = variants.some((variant) => {
1428
- const variantErrors = [];
1429
- _checkValue(value, variant, path, variantErrors);
1430
- return variantErrors.length === 0;
1431
- });
1432
- if (!matchesAny) {
1433
- propError(`Value of "${label}" does not match any of the allowed types`);
1434
- return;
1435
- }
1436
- }
1437
- if (schema.type) {
1438
- const types = Array.isArray(schema.type) ? schema.type : [schema.type];
1439
- if (!types.some((type) => _matchesType(value, type))) {
1440
- propError(`Expected "${label}" to be of type ${types.join(" | ")}, but got ${_typeOf(value)}`);
1441
- return;
1442
- }
1443
- }
1444
- if (Array.isArray(value) && schema.items && !Array.isArray(schema.items)) {
1445
- value.forEach((item, index) => _checkValue(item, schema.items, `${label}[${index}]`, errors));
1446
- }
1447
- if (value && typeof value === "object" && !Array.isArray(value)) {
1448
- const record = value;
1449
- const properties = _nullishCoalesce(schema.properties, () => ( {}));
1450
- for (const requiredKey of _nullishCoalesce(schema.required, () => ( []))) {
1451
- if (record[requiredKey] === void 0) {
1452
- errors.push({
1453
- code: "missing-required-prop",
1454
- message: `Missing required prop "${path ? `${path}.` : ""}${requiredKey}"`,
1455
- path: path ? `${path}.${requiredKey}` : requiredKey
1456
- });
1457
- }
1458
- }
1459
- for (const [key, propValue] of Object.entries(record)) {
1460
- const propSchema = properties[key];
1461
- const propPath = path ? `${path}.${key}` : key;
1462
- if (propSchema === void 0) {
1463
- if (schema.additionalProperties === false) {
1464
- errors.push({
1465
- code: "unexpected-prop",
1466
- message: `Unexpected prop "${propPath}"`,
1467
- path: propPath
1468
- });
1469
- }
1470
- continue;
1471
- }
1472
- _checkValue(propValue, propSchema, propPath, errors);
1473
- }
1474
- }
1626
+ const _isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
1627
+ /**
1628
+ * Minimal JSON-schema subset checker covering what component schemas need:
1629
+ * type, enum, const, required, properties, additionalProperties, items, anyOf/oneOf.
1630
+ * Unknown keywords are ignored (lenient by design).
1631
+ */
1632
+ const _checkValue = (value, schema, path, errors) => {
1633
+ if (schema === void 0 || typeof schema === "boolean" || typeof schema !== "object") return;
1634
+ const label = path || "props";
1635
+ const propError = (message) => {
1636
+ errors.push({
1637
+ code: "invalid-prop-value",
1638
+ message,
1639
+ path: path || void 0
1640
+ });
1641
+ };
1642
+ if (schema.const !== void 0 && !_isEqual(value, schema.const)) {
1643
+ propError(`Expected "${label}" to equal ${JSON.stringify(schema.const)}`);
1644
+ return;
1645
+ }
1646
+ if (schema.enum && !schema.enum.some((allowed) => _isEqual(value, allowed))) {
1647
+ propError(`Expected "${label}" to be one of: ${schema.enum.map((v) => JSON.stringify(v)).join(", ")}`);
1648
+ return;
1649
+ }
1650
+ const variants = schema.anyOf ?? schema.oneOf;
1651
+ if (variants === null || variants === void 0 ? void 0 : variants.length) {
1652
+ if (!variants.some((variant) => {
1653
+ const variantErrors = [];
1654
+ _checkValue(value, variant, path, variantErrors);
1655
+ return variantErrors.length === 0;
1656
+ })) {
1657
+ propError(`Value of "${label}" does not match any of the allowed types`);
1658
+ return;
1659
+ }
1660
+ }
1661
+ if (schema.type) {
1662
+ const types = Array.isArray(schema.type) ? schema.type : [schema.type];
1663
+ if (!types.some((type) => _matchesType(value, type))) {
1664
+ propError(`Expected "${label}" to be of type ${types.join(" | ")}, but got ${_typeOf(value)}`);
1665
+ return;
1666
+ }
1667
+ }
1668
+ if (Array.isArray(value) && schema.items && !Array.isArray(schema.items)) value.forEach((item, index) => _checkValue(item, schema.items, `${label}[${index}]`, errors));
1669
+ if (value && typeof value === "object" && !Array.isArray(value)) {
1670
+ const record = value;
1671
+ const properties = schema.properties ?? {};
1672
+ for (const requiredKey of schema.required ?? []) if (record[requiredKey] === void 0) errors.push({
1673
+ code: "missing-required-prop",
1674
+ message: `Missing required prop "${path ? `${path}.` : ""}${requiredKey}"`,
1675
+ path: path ? `${path}.${requiredKey}` : requiredKey
1676
+ });
1677
+ for (const [key, propValue] of Object.entries(record)) {
1678
+ const propSchema = properties[key];
1679
+ const propPath = path ? `${path}.${key}` : key;
1680
+ if (propSchema === void 0) {
1681
+ if (schema.additionalProperties === false) errors.push({
1682
+ code: "unexpected-prop",
1683
+ message: `Unexpected prop "${propPath}"`,
1684
+ path: propPath
1685
+ });
1686
+ continue;
1687
+ }
1688
+ _checkValue(propValue, propSchema, propPath, errors);
1689
+ }
1690
+ }
1475
1691
  };
1476
-
1477
- // src/message-stream/sanitize.ts
1478
- var sanitizeMessageText = (value, options = {}) => value.replaceAll(_chunkKTDBAJBBcjs.MARKER, _nullishCoalesce(options.markerReplacement, () => ( "\u25AA")));
1479
-
1480
- // src/index.ts
1481
- var utils = {
1482
- toValidObjectName: _chunkGOWPACSKcjs.toValidObjectName,
1483
- toValidFunctionName: _chunkGOWPACSKcjs.toValidFunctionName,
1484
- wrapContent: _chunkHEAQAEFZcjs.wrapContent,
1485
- truncateWrappedContent: _chunkHEAQAEFZcjs.truncateWrappedContent,
1486
- stripTruncationTags: _chunkHEAQAEFZcjs.stripTruncationTags
1692
+ //#endregion
1693
+ //#region src/message-stream/sanitize.ts
1694
+ /**
1695
+ * The protocol has no escaping mechanism by design. Any untrusted text that is
1696
+ * inserted into model context (user messages, tool results, documents) must be
1697
+ * sanitized so it cannot inject protocol blocks.
1698
+ */
1699
+ const sanitizeMessageText = (value, options = {}) => value.replaceAll("■", options.markerReplacement ?? "▪");
1700
+ //#endregion
1701
+ //#region src/index.ts
1702
+ const utils = {
1703
+ toValidObjectName: require_utils.toValidObjectName,
1704
+ toValidFunctionName: require_utils.toValidFunctionName,
1705
+ wrapContent: require_truncator.wrapContent,
1706
+ truncateWrappedContent: require_truncator.truncateWrappedContent,
1707
+ stripTruncationTags: require_truncator.stripTruncationTags
1487
1708
  };
1488
- var execute = async (props) => {
1489
- const { executeContext } = await Promise.resolve().then(() => _interopRequireWildcard(require("./execute-IK6O4SU2.cjs")));
1490
- return executeContext(props);
1709
+ /**
1710
+ * Executes an LLMz agent in either Chat Mode or Worker Mode.
1711
+ *
1712
+ * LLMz is a code-first AI agent framework that generates and runs TypeScript code
1713
+ * in a sandbox rather than using traditional JSON tool calling. This enables complex
1714
+ * logic, multi-tool orchestration, and native LLM thinking via comments and code structure.
1715
+ *
1716
+ * @param props - Configuration object for the execution
1717
+ * @param props.client - Botpress Client or Cognitive Client instance for LLM generation
1718
+ * @param props.instructions - System prompt/instructions for the LLM (static string or dynamic function)
1719
+ * @param props.chat - Optional Chat instance to enable Chat Mode with user interaction
1720
+ * @param props.tools - Array of Tool instances available to the agent (static or dynamic)
1721
+ * @param props.objects - Array of ObjectInstance for namespaced tools and variables (static or dynamic)
1722
+ * @param props.exits - Array of Exit definitions for structured completion (static or dynamic)
1723
+ * @param props.snapshot - Optional Snapshot to resume paused execution
1724
+ * @param props.signal - Optional AbortSignal to cancel execution
1725
+ * @param props.model - Optional model name (or array or models to use as fallback) (static or dynamic function)
1726
+ * @param props.temperature - Optional temperature value (static or dynamic function)
1727
+ * @param props.metadata - Optional metadata attached to cognitive usage records for each LLM call
1728
+ * @param props.options - Optional execution options (loop limit, timeout, maxTokens context cap)
1729
+ * @param props.onTrace - Optional non-blocking hook for monitoring traces during execution
1730
+ * @param props.onIterationEnd - Optional blocking hook called after each iteration
1731
+ * @param props.onExit - Optional blocking hook called when an exit is reached (can prevent exit)
1732
+ * @param props.onBeforeExecution - Optional blocking hook to modify code before VM execution
1733
+ * @param props.onBeforeTool - Optional blocking hook to modify tool inputs before execution
1734
+ * @param props.onAfterTool - Optional blocking hook to modify tool outputs after execution
1735
+ *
1736
+ * @returns Promise<ExecutionResult> - Result containing success/error/interrupted status with type-safe exit checking
1737
+ *
1738
+ * @example
1739
+ * // Worker Mode - Automated execution
1740
+ * const result = await execute({
1741
+ * client: cognitiveClient,
1742
+ * instructions: 'Calculate the sum of numbers 1 to 100',
1743
+ * exits: [myExit]
1744
+ * })
1745
+ *
1746
+ * if (result.is(myExit)) {
1747
+ * console.log('Result:', result.output)
1748
+ * }
1749
+ *
1750
+ * @example
1751
+ * // Chat Mode - Interactive conversation
1752
+ * const result = await execute({
1753
+ * client: cognitiveClient,
1754
+ * instructions: 'You are a helpful assistant',
1755
+ * chat: myChatInstance,
1756
+ * tools: [searchTool, calculatorTool]
1757
+ * })
1758
+ *
1759
+ * if (result.is(ListenExit)) {
1760
+ * // Agent is waiting for user input
1761
+ * }
1762
+ *
1763
+ * @example
1764
+ * // With dynamic instructions and hooks
1765
+ * const result = await execute({
1766
+ * client: cognitiveClient,
1767
+ * instructions: (ctx) => `Process ${ctx.variables.dataCount} records`,
1768
+ * tools: async (ctx) => await getContextualTools(ctx),
1769
+ * model: 'best',
1770
+ * temperature: 0.1,
1771
+ * options: { loop: 10 },
1772
+ * onTrace: ({ trace, iteration }) => console.log(trace),
1773
+ * onExit: async (result) => await validateResult(result)
1774
+ * })
1775
+ */
1776
+ const execute = async (props) => {
1777
+ const { executeContext } = await Promise.resolve().then(() => require("./execute-BEaq3jkV.cjs"));
1778
+ return executeContext(props);
1491
1779
  };
1492
- var init = async () => {
1493
- await Promise.resolve().then(() => _interopRequireWildcard(require("./execute-IK6O4SU2.cjs")));
1494
- await Promise.resolve().then(() => _interopRequireWildcard(require("./component-2NYFY6CW.cjs")));
1495
- await Promise.resolve().then(() => _interopRequireWildcard(require("./tool-VE2YHIY2.cjs")));
1496
- await Promise.resolve().then(() => _interopRequireWildcard(require("./exit-MX56VN2C.cjs")));
1497
- await Promise.resolve().then(() => _interopRequireWildcard(require("./jsx-ULPWX5TW.cjs")));
1498
- await Promise.resolve().then(() => _interopRequireWildcard(require("./vm-6D3IIIU7.cjs")));
1499
- await Promise.resolve().then(() => _interopRequireWildcard(require("./utils-ITB4NEL7.cjs")));
1500
- await Promise.resolve().then(() => _interopRequireWildcard(require("./truncator-FZNLYSDL.cjs")));
1501
- await Promise.resolve().then(() => _interopRequireWildcard(require("./typings-LQOBZXSO.cjs")));
1502
- await Promise.resolve().then(() => _interopRequireWildcard(require("./dual-modes-TCMWBZIH.cjs")));
1780
+ /**
1781
+ * Loads the necessary dependencies for the library to work
1782
+ * Calling this function is optional, but it will improve the performance of the first call to `executeContext`
1783
+ * It's recommended to call this function at the beginning of your application without awaiting it (void init())
1784
+ */
1785
+ const init = async () => {
1786
+ await Promise.resolve().then(() => require("./execute-BEaq3jkV.cjs"));
1787
+ await Promise.resolve().then(() => require("./component-BwixNVH8.cjs")).then((n) => n.component_exports);
1788
+ await Promise.resolve().then(() => require("./tool-DdPZb0JW.cjs")).then((n) => n.tool_exports);
1789
+ await Promise.resolve().then(() => require("./exit-BGi0Kk0y.cjs")).then((n) => n.exit_exports);
1790
+ await Promise.resolve().then(() => require("./jsx-BWvT6ukg.cjs")).then((n) => n.jsx_exports);
1791
+ await Promise.resolve().then(() => require("./vm-BjkJqSQH.cjs"));
1792
+ await Promise.resolve().then(() => require("./utils-ZpJm00ed.cjs")).then((n) => n.utils_exports);
1793
+ await Promise.resolve().then(() => require("./truncator-B6aaJaN1.cjs")).then((n) => n.truncator_exports);
1794
+ await Promise.resolve().then(() => require("./typings-BwAz_TM9.cjs")).then((n) => n.typings_exports);
1795
+ await Promise.resolve().then(() => require("./dual-modes-wAOAlaBS.cjs")).then((n) => n.dual_modes_exports);
1503
1796
  };
1504
-
1505
-
1506
-
1507
-
1508
-
1509
-
1510
-
1511
-
1512
-
1513
-
1514
-
1515
-
1516
-
1517
-
1518
-
1519
-
1520
-
1521
-
1522
-
1523
-
1524
-
1525
-
1526
-
1527
-
1528
-
1529
-
1530
-
1531
-
1532
-
1533
-
1534
-
1535
-
1536
-
1537
-
1538
-
1539
-
1540
-
1541
-
1542
-
1543
-
1544
-
1545
-
1546
-
1547
-
1548
-
1549
-
1550
-
1551
-
1552
-
1553
-
1554
-
1555
- exports.BaseResponse = BaseResponse; exports.Chat = Chat; exports.CitationsManager = CitationsManager; exports.Component = _chunkI56MPOVGcjs.Component; exports.ComponentRegistry = ComponentRegistry; exports.DefaultComponents = DefaultComponents; exports.DefaultExit = _chunk5WBNTV42cjs.DefaultExit; exports.ErrorExecutionResult = _chunk5WBNTV42cjs.ErrorExecutionResult; exports.ExecutionResult = _chunk5WBNTV42cjs.ExecutionResult; exports.Exit = _chunkDDSJTR6Qcjs.Exit; exports.ListenExit = _chunk5WBNTV42cjs.ListenExit; exports.LoopExceededError = _chunkPK72FAKDcjs.LoopExceededError; exports.MARKER = _chunkKTDBAJBBcjs.MARKER; exports.NAME_REGEX = _chunkKTDBAJBBcjs.NAME_REGEX; exports.NextResponse = NextResponse; exports.ObjectInstance = ObjectInstance; exports.PartialExecutionResult = _chunk5WBNTV42cjs.PartialExecutionResult; exports.ReplayableAsyncIterable = ReplayableAsyncIterable; exports.RunResponse = RunResponse; exports.SendResponse = SendResponse; exports.Snapshot = _chunk5WBNTV42cjs.Snapshot; exports.SnapshotSignal = _chunkPK72FAKDcjs.SnapshotSignal; exports.StreamingMessageParser = _chunkKTDBAJBBcjs.StreamingMessageParser; exports.SuccessExecutionResult = _chunk5WBNTV42cjs.SuccessExecutionResult; exports.ThinkExit = _chunk5WBNTV42cjs.ThinkExit; exports.ThinkSignal = _chunkPK72FAKDcjs.ThinkSignal; exports.Tool = _chunkPZE6PIPGcjs.Tool; exports._CustomModelClient = _chunk5WBNTV42cjs._CustomModelClient; exports.assertValidComponent = _chunkI56MPOVGcjs.assertValidComponent; exports.collectText = collectText; exports.configureQuickJS = _chunkRGUG3UMFcjs.configureQuickJS; exports.configureTokenizer = _chunkGOWPACSKcjs.configureTokenizer; exports.execute = execute; exports.generateInstructions = _chunkKTDBAJBBcjs.generateInstructions; exports.getValue = _chunk5WBNTV42cjs.getValue; exports.init = init; exports.isAnyComponent = _chunkI56MPOVGcjs.isAnyComponent; exports.isComponent = _chunkI56MPOVGcjs.isComponent; exports.normalizeComponentDefinition = normalizeComponentDefinition; exports.normalizeComponentName = normalizeComponentName; exports.normalizePropsSchema = normalizePropsSchema; exports.parseExit = _chunk5WBNTV42cjs.parseExit; exports.parseStream = parseStream; exports.parseText = parseText; exports.sanitizeMessageText = sanitizeMessageText; exports.tryParseJson = _chunkKTDBAJBBcjs.tryParseJson; exports.utils = utils; exports.validateComponent = validateComponent; exports.validateProps = validateProps; exports.version = version;
1797
+ //#endregion
1798
+ exports.BaseResponse = BaseResponse;
1799
+ exports.Chat = Chat;
1800
+ exports.CitationsManager = CitationsManager;
1801
+ exports.Component = require_component.Component;
1802
+ exports.ComponentRegistry = ComponentRegistry;
1803
+ exports.DefaultComponents = DefaultComponents;
1804
+ exports.DefaultExit = require_custom_client.DefaultExit;
1805
+ exports.ErrorExecutionResult = require_custom_client.ErrorExecutionResult;
1806
+ exports.ExecutionResult = require_custom_client.ExecutionResult;
1807
+ exports.Exit = require_exit.Exit;
1808
+ exports.ListenExit = require_custom_client.ListenExit;
1809
+ exports.LoopExceededError = require_errors.LoopExceededError;
1810
+ exports.MARKER = require_dual_modes.MARKER;
1811
+ exports.NAME_REGEX = require_dual_modes.NAME_REGEX;
1812
+ exports.NextResponse = NextResponse;
1813
+ exports.ObjectInstance = ObjectInstance;
1814
+ exports.PartialExecutionResult = require_custom_client.PartialExecutionResult;
1815
+ exports.ReplayableAsyncIterable = ReplayableAsyncIterable;
1816
+ exports.RunResponse = RunResponse;
1817
+ exports.SendResponse = SendResponse;
1818
+ exports.Snapshot = require_custom_client.Snapshot;
1819
+ exports.SnapshotSignal = require_errors.SnapshotSignal;
1820
+ exports.StreamingMessageParser = require_dual_modes.StreamingMessageParser;
1821
+ exports.SuccessExecutionResult = require_custom_client.SuccessExecutionResult;
1822
+ exports.ThinkExit = require_custom_client.ThinkExit;
1823
+ exports.ThinkSignal = require_errors.ThinkSignal;
1824
+ exports.Tool = require_tool.Tool;
1825
+ exports._CustomModelClient = require_custom_client._CustomModelClient;
1826
+ exports.assertValidComponent = require_component.assertValidComponent;
1827
+ exports.collectText = collectText;
1828
+ exports.configureQuickJS = require_quickjs_variant.configureQuickJS;
1829
+ exports.configureTokenizer = require_utils.configureTokenizer;
1830
+ exports.execute = execute;
1831
+ exports.generateInstructions = require_dual_modes.generateInstructions;
1832
+ exports.getValue = require_custom_client.getValue;
1833
+ exports.init = init;
1834
+ exports.isAnyComponent = require_component.isAnyComponent;
1835
+ exports.isComponent = require_component.isComponent;
1836
+ exports.normalizeComponentDefinition = normalizeComponentDefinition;
1837
+ exports.normalizeComponentName = normalizeComponentName;
1838
+ exports.normalizePropsSchema = normalizePropsSchema;
1839
+ exports.parseExit = require_custom_client.parseExit;
1840
+ exports.parseStream = parseStream;
1841
+ exports.parseText = parseText;
1842
+ exports.sanitizeMessageText = sanitizeMessageText;
1843
+ exports.tryParseJson = require_dual_modes.tryParseJson;
1844
+ exports.utils = utils;
1845
+ exports.validateComponent = validateComponent;
1846
+ exports.validateProps = validateProps;
1847
+ Object.defineProperty(exports, "version", {
1848
+ enumerable: true,
1849
+ get: function() {
1850
+ return version;
1851
+ }
1852
+ });