llmz 0.8.0 → 1.0.1

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 (224) hide show
  1. package/DOCS.md +230 -1796
  2. package/ERRORS.md +98 -0
  3. package/README.md +96 -548
  4. package/dist/chat/chat.d.ts +63 -0
  5. package/dist/chat/component.d.ts +31 -0
  6. package/dist/chat/component.default.d.ts +58 -0
  7. package/dist/chat/response.d.ts +15 -0
  8. package/dist/compiler/compiler.d.ts +2 -7
  9. package/dist/compiler/plugins/dynamic-code.d.ts +7 -0
  10. package/dist/compiler/plugins/replace-comment.d.ts +2 -3
  11. package/dist/compiler/plugins/return-async.d.ts +5 -4
  12. package/dist/compiler/plugins/termination.d.ts +8 -0
  13. package/dist/compiler/plugins/tool-resolution.d.ts +4 -0
  14. package/dist/compiler/plugins/variable-extraction.d.ts +2 -8
  15. package/dist/component-BpMVZYOa.cjs +649 -0
  16. package/dist/component-C27qu6Zv.js +614 -0
  17. package/dist/context.d.ts +74 -385
  18. package/dist/custom-client-BDkgBR2w.js +1631 -0
  19. package/dist/custom-client-MytucGI-.cjs +1708 -0
  20. package/dist/custom-client.d.ts +12 -2
  21. package/dist/errors/catalog.d.ts +287 -0
  22. package/dist/errors/hooks.d.ts +2 -0
  23. package/dist/errors-H4JJFH3S.js +620 -0
  24. package/dist/errors-IhnTKUp7.cjs +871 -0
  25. package/dist/errors.d.ts +18 -36
  26. package/dist/execute-BYI_U5sR.js +1943 -0
  27. package/dist/execute-DLas4V2n.cjs +1944 -0
  28. package/dist/{exit-DUM96DN1.cjs → exit-BUgJ5qi5.cjs} +38 -28
  29. package/dist/{exit-CDdxDBRT.js → exit-CPNk3vbz.js} +37 -27
  30. package/dist/exit.d.ts +19 -16
  31. package/dist/index.cjs +181 -999
  32. package/dist/index.d.ts +25 -28
  33. package/dist/index.js +141 -974
  34. package/dist/index.workerd.js +7725 -9531
  35. package/dist/inspect.d.ts +19 -3
  36. package/dist/inspection.d.ts +38 -0
  37. package/dist/native-Bm6L9zOb.cjs +212 -0
  38. package/dist/native-DvTH9vFe.js +177 -0
  39. package/dist/objects.d.ts +2 -57
  40. package/dist/prompts/native.d.ts +2 -0
  41. package/dist/prompts/prompt.d.ts +10 -98
  42. package/dist/quickjs-variant-DJwYDSsb.cjs +1073 -0
  43. package/dist/quickjs-variant-DlPi9-Sx.js +984 -0
  44. package/dist/result.d.ts +30 -861
  45. package/dist/runtime/execute.d.ts +3 -2
  46. package/dist/runtime/execution-activity.d.ts +11 -0
  47. package/dist/runtime/execution-activity.test.d.ts +1 -0
  48. package/dist/runtime/execution-diagnostics.d.ts +11 -0
  49. package/dist/runtime/execution-diagnostics.test.d.ts +1 -0
  50. package/dist/runtime/execution-report.d.ts +48 -0
  51. package/dist/runtime/execution-report.test.d.ts +1 -0
  52. package/dist/runtime/execution-safety.test.d.ts +1 -0
  53. package/dist/runtime/exit-control-flow.test.d.ts +1 -0
  54. package/dist/runtime/fixtures/chat.d.ts +8 -0
  55. package/dist/runtime/fixtures/long-search.d.ts +19 -0
  56. package/dist/runtime/fixtures/long-search.test.d.ts +1 -0
  57. package/dist/runtime/fixtures/native-client.d.ts +33 -0
  58. package/dist/runtime/fixtures/protocol-languages.d.ts +74 -0
  59. package/dist/runtime/generate.d.ts +23 -27
  60. package/dist/runtime/generate.test.d.ts +1 -0
  61. package/dist/runtime/hook-provenance.test.d.ts +1 -0
  62. package/dist/runtime/inspection-hook.test.d.ts +1 -0
  63. package/dist/runtime/inspection-values.d.ts +14 -0
  64. package/dist/runtime/inspection-values.test.d.ts +1 -0
  65. package/dist/runtime/interruption-control-flow.test.d.ts +1 -0
  66. package/dist/runtime/interruption-settings.test.d.ts +1 -0
  67. package/dist/runtime/javascript-api.d.ts +59 -0
  68. package/dist/runtime/javascript-api.test.d.ts +1 -0
  69. package/dist/runtime/native-review.test.d.ts +1 -0
  70. package/dist/runtime/native-tools.d.ts +18 -0
  71. package/dist/runtime/native-tools.test.d.ts +1 -0
  72. package/dist/runtime/object-memory.test.d.ts +1 -0
  73. package/dist/runtime/protocol-adherence.test.d.ts +1 -0
  74. package/dist/runtime/single-tool.test.d.ts +1 -0
  75. package/dist/runtime/token-budget.d.ts +22 -0
  76. package/dist/runtime/token-budget.test.d.ts +1 -0
  77. package/dist/runtime/tool-wrapper.d.ts +4 -5
  78. package/dist/runtime/traces.test.d.ts +1 -0
  79. package/dist/runtime/truncation.test.d.ts +1 -0
  80. package/dist/runtime/types.d.ts +41 -36
  81. package/dist/runtime/variable-recovery.test.d.ts +1 -0
  82. package/dist/runtime/vm-context.d.ts +6 -1
  83. package/dist/runtime/worker-completion.test.d.ts +1 -0
  84. package/dist/runtime-names.d.ts +4 -0
  85. package/dist/schema-Aer_W7Al.js +45 -0
  86. package/dist/schema-DBkjo0b7.cjs +68 -0
  87. package/dist/schema.d.ts +10 -0
  88. package/dist/schema.test.d.ts +1 -0
  89. package/dist/session/compactor.d.ts +51 -0
  90. package/dist/session/compactor.test.d.ts +1 -0
  91. package/dist/session/history.d.ts +36 -0
  92. package/dist/session/history.test.d.ts +1 -0
  93. package/dist/session/json.d.ts +3 -0
  94. package/dist/session/json.test.d.ts +1 -0
  95. package/dist/session/memory-codec.d.ts +9 -0
  96. package/dist/session/memory-codec.test.d.ts +1 -0
  97. package/dist/session/memory-render.d.ts +15 -0
  98. package/dist/session/memory-render.test.d.ts +1 -0
  99. package/dist/session/memory.d.ts +112 -0
  100. package/dist/session/memory.test.d.ts +1 -0
  101. package/dist/session/messages.d.ts +17 -0
  102. package/dist/session/messages.test.d.ts +1 -0
  103. package/dist/session/serialization.d.ts +34 -0
  104. package/dist/session/serialization.test.d.ts +1 -0
  105. package/dist/session/session-memory.test.d.ts +1 -0
  106. package/dist/session/session.d.ts +117 -0
  107. package/dist/session/session.test.d.ts +1 -0
  108. package/dist/{transcript.d.ts → session/transcript.d.ts} +4 -8
  109. package/dist/session/transcript.test.d.ts +1 -0
  110. package/dist/{tool-Bv8N4IPj.js → tool--gK91eez.js} +144 -92
  111. package/dist/{tool-Dy6AJpJH.cjs → tool-Da_F-N-5.cjs} +146 -94
  112. package/dist/tool.d.ts +25 -17
  113. package/dist/truncate-BSoH2-nY.js +79 -0
  114. package/dist/truncate-nV3Mxr6-.cjs +102 -0
  115. package/dist/truncate.d.ts +24 -0
  116. package/dist/truncate.test.d.ts +1 -0
  117. package/dist/types.d.ts +27 -9
  118. package/dist/{typings-3lsqCbkn.cjs → typings-C1ihexWE.cjs} +38 -193
  119. package/dist/{typings-CrBa7Tyy.js → typings-D9_aC8aq.js} +38 -175
  120. package/dist/typings-formatter.d.ts +1 -1
  121. package/dist/typings.d.ts +3 -0
  122. package/dist/{uniq-BYQ7GWwb.js → uniq-DfUeSNaX.js} +2 -2
  123. package/dist/{uniq-G872RWmE.cjs → uniq-DiXgysNV.cjs} +6 -18
  124. package/dist/{_baseIteratee-P_firB7b.js → utils-BOFzb8Ok.js} +1134 -16
  125. package/dist/{_baseIteratee-CF4qP2a8.cjs → utils-CTlsXvdj.cjs} +1281 -84
  126. package/dist/vm/drivers/node.d.ts +1 -1
  127. package/dist/vm/drivers/quickjs.d.ts +1 -1
  128. package/dist/vm/errors.d.ts +4 -4
  129. package/dist/vm/index.d.ts +3 -4
  130. package/dist/vm/instrument.d.ts +14 -6
  131. package/dist/vm/member-proxy.d.ts +4 -0
  132. package/dist/vm/member-proxy.test.d.ts +1 -0
  133. package/dist/vm/memory.test.d.ts +1 -0
  134. package/dist/vm/return-semantics.test.d.ts +1 -0
  135. package/dist/vm/types.d.ts +18 -3
  136. package/dist/{vm-BLsHw1da.js → vm-8jxt8PTK.js} +1162 -180
  137. package/dist/{vm-D6s1zF6M.cjs → vm-XuVPuW3Y.cjs} +1195 -207
  138. package/package.json +13 -6
  139. package/dist/_baseForOwn-BfWDTL8L.cjs +0 -53
  140. package/dist/_baseForOwn-CFhWe_W6.js +0 -48
  141. package/dist/_getPrototype-CG7Dxrrz.js +0 -6
  142. package/dist/_getPrototype-DQDlNVVM.cjs +0 -10
  143. package/dist/_overArg-C5Hy7oCi.cjs +0 -196
  144. package/dist/_overArg-CRYbj1NH.js +0 -155
  145. package/dist/chat.d.ts +0 -401
  146. package/dist/common-DdArNQhl.cjs +0 -643
  147. package/dist/common-pgJjFu2Y.js +0 -596
  148. package/dist/compiler/plugins/track-tool-calls.d.ts +0 -33
  149. package/dist/compiler-C-OI9sim.cjs +0 -547
  150. package/dist/compiler-CW1VjQsn.js +0 -473
  151. package/dist/component-BXS8vAwO.cjs +0 -73
  152. package/dist/component-Dq7ZLdvy.js +0 -44
  153. package/dist/component.d.ts +0 -88
  154. package/dist/component.default.d.ts +0 -268
  155. package/dist/custom-client-2V9lmzUf.js +0 -2655
  156. package/dist/custom-client-HkM1Sdzv.cjs +0 -2726
  157. package/dist/dual-modes-Cb7ThvoV.cjs +0 -3020
  158. package/dist/dual-modes-Cy0_W4O2.js +0 -2930
  159. package/dist/errors-C962uJdS.cjs +0 -220
  160. package/dist/errors-Cg1G0Awu.js +0 -161
  161. package/dist/example.d.ts +0 -45
  162. package/dist/execute-Aw4cbIx-.js +0 -1080
  163. package/dist/execute-COIHOIKR.cjs +0 -1081
  164. package/dist/exit-parser.d.ts +0 -39
  165. package/dist/handlers.d.ts +0 -10
  166. package/dist/hoist.d.ts +0 -2
  167. package/dist/isEmpty-BhJRCqIF.js +0 -52
  168. package/dist/isEmpty-LY533Wmh.cjs +0 -57
  169. package/dist/jsx-B0iYyvfr.js +0 -100
  170. package/dist/jsx-D5Y2cPo-.cjs +0 -129
  171. package/dist/jsx.d.ts +0 -11
  172. package/dist/message-stream/index.d.ts +0 -9
  173. package/dist/message-stream/instructions.d.ts +0 -22
  174. package/dist/message-stream/normalizer.d.ts +0 -21
  175. package/dist/message-stream/parser.d.ts +0 -83
  176. package/dist/message-stream/registry.d.ts +0 -14
  177. package/dist/message-stream/replayable.d.ts +0 -27
  178. package/dist/message-stream/sanitize.d.ts +0 -10
  179. package/dist/message-stream/stream.d.ts +0 -54
  180. package/dist/message-stream/types.d.ts +0 -96
  181. package/dist/message-stream/validator.d.ts +0 -23
  182. package/dist/prompts/chat-mode/system.d.ts +0 -2
  183. package/dist/prompts/chat-mode/system.md.d.ts +0 -2
  184. package/dist/prompts/chat-mode/user.d.ts +0 -2
  185. package/dist/prompts/chat-mode/user.md.d.ts +0 -2
  186. package/dist/prompts/common.d.ts +0 -6
  187. package/dist/prompts/dual-modes.d.ts +0 -2
  188. package/dist/prompts/execution-history.d.ts +0 -6
  189. package/dist/prompts/execution-state.d.ts +0 -3
  190. package/dist/prompts/protocol.d.ts +0 -18
  191. package/dist/prompts/worker-mode/system.d.ts +0 -2
  192. package/dist/prompts/worker-mode/system.md.d.ts +0 -2
  193. package/dist/prompts/worker-mode/user.d.ts +0 -2
  194. package/dist/prompts/worker-mode/user.md.d.ts +0 -2
  195. package/dist/quickjs-variant-BYhMBpwU.js +0 -45
  196. package/dist/quickjs-variant-CsIwTVFC.cjs +0 -56
  197. package/dist/rolldown-runtime-EAsCxrDo.js +0 -14
  198. package/dist/runtime/interpret-result.d.ts +0 -22
  199. package/dist/snapshots.d.ts +0 -249
  200. package/dist/stack-traces-BIE_5Xwf.js +0 -21
  201. package/dist/stack-traces-ntw_qhoy.cjs +0 -26
  202. package/dist/truncator-CLkouTCO.cjs +0 -276
  203. package/dist/truncator-DZqEqnpD.js +0 -253
  204. package/dist/truncator.d.ts +0 -118
  205. package/dist/utils-3ESwP3yg.cjs +0 -1075
  206. package/dist/utils-UBeAFeEI.js +0 -950
  207. /package/dist/{citations.d.ts → chat/citations.d.ts} +0 -0
  208. /package/dist/{citations.test.d.ts → chat/citations.test.d.ts} +0 -0
  209. /package/dist/{component.default.test.d.ts → chat/component.default.test.d.ts} +0 -0
  210. /package/dist/{compiler/plugins/track-tool-calls.test.d.ts → chat/component.test.d.ts} +0 -0
  211. /package/dist/{example.test.d.ts → chat/response.test.d.ts} +0 -0
  212. /package/dist/{exit-parser.test.d.ts → compiler/plugins/dynamic-code.test.d.ts} +0 -0
  213. /package/dist/{handlers.test.d.ts → compiler/plugins/tool-resolution.test.d.ts} +0 -0
  214. /package/dist/{hoist.test.d.ts → errors/catalog.test.d.ts} +0 -0
  215. /package/dist/{message-stream/instructions.test.d.ts → exit.test.d.ts} +0 -0
  216. /package/dist/{message-stream/normalizer.test.d.ts → inspection.test.d.ts} +0 -0
  217. /package/dist/{message-stream/parser.test.d.ts → prompts/native.test.d.ts} +0 -0
  218. /package/dist/{message-stream/stream.test.d.ts → result.test.d.ts} +0 -0
  219. /package/dist/{message-stream/validator.test.d.ts → runtime/chat-delivery.test.d.ts} +0 -0
  220. /package/dist/{prompts/common.test.d.ts → runtime/citations.test.d.ts} +0 -0
  221. /package/dist/{prompts/protocol.test.d.ts → runtime/compatibility-regressions.test.d.ts} +0 -0
  222. /package/dist/runtime/{interpret-result.test.d.ts → context-registration.test.d.ts} +0 -0
  223. /package/dist/{transcript.test.d.ts → runtime/error-recovery.test.d.ts} +0 -0
  224. /package/dist/{truncator.test.d.ts → runtime/errors.test.d.ts} +0 -0
package/dist/index.js CHANGED
@@ -1,199 +1,17 @@
1
- import { a as StreamingMessageParser, c as NAME_REGEX, o as tryParseJson, s as MARKER } from "./common-pgJjFu2Y.js";
2
- import { a as Example, h as ComponentRegistry, m as validateProps, o as generateInstructions, p as validateComponent, s as DefaultComponents } from "./dual-modes-Cy0_W4O2.js";
3
- import { a as ThinkExit, c as ExecutionResult, d as Snapshot, f as parseExit, i as ListenExit, l as PartialExecutionResult, o as getValue, r as DefaultExit, s as ErrorExecutionResult, t as _CustomModelClient, u as SuccessExecutionResult } from "./custom-client-2V9lmzUf.js";
4
- import { a as getMultilineComment, c as isJsonSchema, l as isValidIdentifier, m as toValidObjectName, n as escapeString, p as toValidFunctionName, t as configureTokenizer, u as isZuiSchema, v as upperFirst } from "./utils-UBeAFeEI.js";
5
- import { a as isComponent, i as isAnyComponent, n as assertValidComponent, t as Component } from "./component-Dq7ZLdvy.js";
6
- import { t as Tool } from "./tool-Bv8N4IPj.js";
7
- import { c as SnapshotSignal, l as ThinkSignal, o as LoopExceededError, r as CodeFormattingError } from "./errors-Cg1G0Awu.js";
8
- import { a as isPunct, i as isGroup, o as parse, r as formatTypings, s as tokenize, t as getTypings } from "./typings-CrBa7Tyy.js";
9
- import { t as Exit } from "./exit-CDdxDBRT.js";
10
- import { i as wrapContent, n as truncateWrappedContent, t as stripTruncationTags } from "./truncator-DZqEqnpD.js";
11
- import { t as configureQuickJS } from "./quickjs-variant-BYhMBpwU.js";
12
- import { transforms, z } from "@bpinternal/zui";
1
+ import { c as isValidIdentifier, f as toValidFunctionName, i as getMultilineComment, p as toValidObjectName, t as configureTokenizer } from "./utils-BOFzb8Ok.js";
2
+ import { A as MemoryValueError, B as UnknownToolError, C as InvalidMessageError, D as LLMzError, E as InvalidToolError, F as TokenOverflowError, H as isLLMzError, I as ToolExecutionError, L as ToolInputError, M as ObjectPropertyError, N as ReservedIdentifierError, O as LoopExceededError, P as SessionStateError, R as UnknownComponentError, S as InvalidExitError, T as InvalidSessionError, V as isCriticalError, _ as InternalError, b as InvalidConfigurationError, c as CodeFormattingError, d as ComponentInputError, f as DeliveryError, g as HostOperationError, h as HookError, j as NativeProtocolError, k as MemoryCapacityError, l as CognitiveError, m as ExitInputError, n as ThinkSignal, o as AssignmentError, p as ExecutionAbortedError, s as CodeExecutionError, u as CompactionError, v as InvalidCodeError, w as InvalidObjectError, x as InvalidEventError, y as InvalidComponentError, z as UnknownExitError } from "./errors-H4JJFH3S.js";
3
+ import { a as isAnyComponent, n as assertValidComponent, o as isComponent, t as Component } from "./component-C27qu6Zv.js";
4
+ import { t as Tool } from "./tool--gK91eez.js";
5
+ import { t as Exit } from "./exit-CPNk3vbz.js";
6
+ import { r as truncate } from "./truncate-BSoH2-nY.js";
7
+ import { f as createInspector, p as inspect, r as Memory, t as configureQuickJS } from "./quickjs-variant-DlPi9-Sx.js";
8
+ import { i as formatTypings } from "./typings-D9_aC8aq.js";
9
+ import { c as getValue, i as SuccessExecutionResult, l as Session, n as ErrorExecutionResult, o as DefaultExit, r as ExecutionResult, s as ListenExit, t as _CustomModelClient } from "./custom-client-BDkgBR2w.js";
10
+ import { z } from "@bpinternal/zui";
13
11
  //#region package.json
14
- var version = "0.8.0";
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) */
23
- function printNodes(nodes) {
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 (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;
47
- }
48
- /** Canonical structural key of a type literal: comments and separators ignored */
49
- function keyOf(group) {
50
- const parts = [];
51
- const visit = (n) => {
52
- if (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(" ");
60
- }
61
- const prevMeaningful = (siblings, index) => {
62
- for (let i = index - 1; i >= 0; i--) {
63
- const n = siblings[i];
64
- if (isGroup(n) || n.kind !== "block-comment" && n.kind !== "line-comment") return n;
65
- }
66
- };
67
- const asName = (text) => upperFirst(text.replace(/['"]/g, "").replace(/[^A-Za-z0-9_$]/g, ""));
68
- /** The naming segment for a `{`/`<` group from its surrounding tokens (`key:`, `fn(...)`, `): `, `=>`) */
69
- function segmentsAt(siblings, index) {
70
- const prev = prevMeaningful(siblings, index);
71
- if (!prev || isGroup(prev)) return [];
72
- if (isPunct(prev, "=>")) return ["Output"];
73
- if (isPunct(prev, ":") || isPunct(prev, "<")) {
74
- var _kind;
75
- let i = siblings.indexOf(prev) - 1;
76
- while (i >= 0 && !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 && !isGroup(q) && q.kind === "punct" && q.text === "?") q = siblings[--i];
79
- if (q && isGroup(q) && q.open === "(") {
80
- const fnWord = prevMeaningful(siblings, i);
81
- return fnWord && !isGroup(fnWord) && fnWord.kind === "word" ? [asName(fnWord.text), "Output"] : ["Output"];
82
- }
83
- if (q && !isGroup(q) && (q.kind === "word" || q.kind === "string")) return [asName(q.text)];
84
- }
85
- return [];
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
- */
93
- function walkLiterals(siblings, path, visit) {
94
- for (let i = 0; i < siblings.length; i++) {
95
- var _prevMeaningful;
96
- const node = siblings[i];
97
- if (!isGroup(node)) continue;
98
- if (node.open === "(") {
99
- const fnWord = prevMeaningful(siblings, i);
100
- const fnName = fnWord && !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 && isPunct(prev, "=")) {
110
- const eqIdx = siblings.indexOf(prev);
111
- const nameTok = siblings[eqIdx - 1];
112
- const typeTok = siblings[eqIdx - 2];
113
- if (!(nameTok && typeTok && !isGroup(nameTok) && !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 && !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
- }
136
- }
137
- function extractAndHoistTypes(code) {
138
- const top = parse(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;
178
- }
179
- async function hoistTypings(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 CodeFormattingError(err instanceof Error ? err.message : String(err ?? "Unknown Error"), code);
189
- break;
190
- }
191
- return formatTypings(code, formatOptions);
192
- }
12
+ var version = "1.0.1";
193
13
  //#endregion
194
14
  //#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
15
  /**
198
16
  * ObjectInstance creates stateful, namespace-scoped objects for LLMz agents.
199
17
  *
@@ -372,25 +190,6 @@ const LARGE_OBJECT_LINES_OF_CODE = 10;
372
190
  * })
373
191
  * ```
374
192
  *
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
193
  */
395
194
  var ObjectInstance = class {
396
195
  name;
@@ -456,18 +255,19 @@ var ObjectInstance = class {
456
255
  */
457
256
  constructor(props) {
458
257
  var _props$properties;
459
- if (!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}"`);
258
+ if (!props || typeof props !== "object" || Array.isArray(props)) throw new InvalidObjectError("Object definition must be an object.");
259
+ if (!isValidIdentifier(props.name)) throw new InvalidObjectError(`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.`);
260
+ if (props.description !== void 0 && typeof props.description !== "string") throw new InvalidObjectError(`Invalid description for tool ${props.name}. Expected a string, but got type "${typeof props.description}"`);
261
+ if (props.metadata !== void 0 && typeof props.metadata !== "object") throw new InvalidObjectError(`Invalid metadata for tool ${props.name}. Expected an object, but got type "${typeof props.metadata}"`);
262
+ if (props.properties !== void 0 && !Array.isArray(props.properties)) throw new InvalidObjectError(`Invalid properties for tool ${props.name}. Expected an array, but got type "${typeof props.properties}"`);
263
+ if (props.tools !== void 0 && !Array.isArray(props.tools)) throw new InvalidObjectError(`Invalid tools for tool ${props.name}. Expected an array, but got type "${typeof props.tools}"`);
464
264
  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}`);
265
+ if (props.properties.length > 100) throw new InvalidObjectError(`Too many properties for tool ${props.name}. Expected at most 100 properties, but got ${props.properties.length}`);
466
266
  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 (!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}`);
267
+ if (props.properties.filter((p) => p.name === prop.name).length > 1) throw new InvalidObjectError(`Duplicate property name "${prop.name}" in tool ${props.name}`);
268
+ if (!isValidIdentifier(prop.name)) throw new InvalidObjectError(`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.`);
269
+ if (prop.description !== void 0 && typeof prop.description !== "string") throw new InvalidObjectError(`Invalid description for property ${prop.name}. Expected a string, but got type "${typeof prop.description}"`);
270
+ if (props.description && props.description.length >= 5e3) throw new InvalidObjectError(`Description for property ${prop.name} is too long. Expected at most 5000 characters, but got ${props.description.length}`);
471
271
  if (typeof prop.writable !== "boolean") prop.writable = false;
472
272
  }
473
273
  }
@@ -477,45 +277,17 @@ var ObjectInstance = class {
477
277
  this.properties = props.properties;
478
278
  this.tools = Tool.withUniqueNames(props.tools ?? []);
479
279
  }
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();
280
+ /** Callable API only. Property values, schemas, and access rules belong in Memory. */
281
+ async getToolTypings() {
282
+ var _this$description;
283
+ const declarations = [];
284
+ for (const tool of this.tools ?? []) {
285
+ const declaration = await tool.getTypings();
286
+ declarations.push(declaration.replace("declare function ", "function "));
287
+ }
288
+ const description = ((_this$description = this.description) === null || _this$description === void 0 ? void 0 : _this$description.trim()) ? getMultilineComment(this.description) : "";
289
+ const body = declarations.join("\n\n");
290
+ return formatTypings(`${description}\nexport namespace ${this.name} {\n${body}\n}`, { throwOnError: false });
519
291
  }
520
292
  /**
521
293
  * Converts this ObjectInstance to its JSON representation.
@@ -536,123 +308,36 @@ var ObjectInstance = class {
536
308
  };
537
309
  }
538
310
  };
311
+ //#endregion
312
+ //#region src/chat/chat.ts
539
313
  /**
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
- */
549
- function getObjectTypings(obj) {
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(getMultilineComment(description));
565
- let type = "unknown";
566
- if (prop.type) type = await 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 = z.function(tool.zInput, tool.zOutput).title(tool.name).describe(tool.description ?? "");
584
- let temp = await 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 = getMultilineComment(obj.description);
599
- return formatTypings(`${header}
600
- export namespace ${obj.name} {
601
- ${body}
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;
624
- }
625
- /**
626
- * Converts a property value to its TypeScript literal representation.
314
+ * Connects native assistant replies and rich components to the host application.
627
315
  *
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.
316
+ * `response` controls how all assistant text is written. It does not create a
317
+ * JavaScript method or synthesize audio. `components` registers only rich UI
318
+ * methods such as chat.buttons or chat.image.
631
319
  *
632
- * @param property - The ObjectProperty containing the value to embed
633
- * @returns String representation of the value for use in TypeScript code
634
- * @internal
320
+ * Streamed deltas are provisional. After successful generation, the response
321
+ * handler receives the complete text with the same message ID. Each component
322
+ * owns its delivery handler. Without response callbacks, text remains available
323
+ * in the native session history.
635
324
  */
636
- function embedPropertyValue(property) {
637
- if (typeof property.value === "string") return 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(${escapeString(property.value.source)}, ${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(${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";
653
- }
325
+ var Chat = class {
326
+ components;
327
+ response;
328
+ constructor(props = {}) {
329
+ if (!props || typeof props !== "object" || Array.isArray(props)) throw new InvalidConfigurationError("Chat configuration must be an object.");
330
+ if ("handler" in props || "onMessageDelta" in props) throw new InvalidConfigurationError("Use response.handler and response.onDelta for text, and component handlers for rich messages.");
331
+ const unknown = Object.keys(props).find((key) => !["components", "response"].includes(key));
332
+ if (unknown) throw new InvalidConfigurationError(`Unknown Chat option: ${unknown}.`);
333
+ this.components = props.components ?? [];
334
+ this.response = props.response === void 0 ? "markdown" : props.response;
335
+ }
336
+ /** Called after an execution completes or fails. */
337
+ onExecutionDone(_result) {}
338
+ };
654
339
  //#endregion
655
- //#region src/citations.ts
340
+ //#region src/chat/citations.ts
656
341
  /** These are all single-token symbols that are very rare in natural texts, making them suitable for usage within GPT Prompts. */
657
342
  const RARE_SYMBOLS = {
658
343
  ARROW_UP: "↑",
@@ -791,611 +476,95 @@ var CitationsManager = class {
791
476
  }
792
477
  };
793
478
  //#endregion
794
- //#region src/chat.ts
795
- /**
796
- * Base class for implementing chat interfaces in LLMz agents.
797
- *
798
- * The Chat class provides the foundation for interactive conversational agents by defining
799
- * how agents communicate with users. It manages the conversation transcript, available UI
800
- * components, and message handling. This is the bridge between the agent's generated code
801
- * and your user interface.
802
- *
803
- * ## Key Concepts
804
- *
805
- * **Handler Function**: The core method that receives agent messages (rendered components)
806
- * and displays them to the user. This is called every time the agent wants to communicate.
807
- *
808
- * **Transcript**: An up-to-date conversation history that is evaluated at each iteration.
809
- * The transcript must reflect the complete conversation state as the agent uses it to
810
- * understand context and generate appropriate responses.
811
- *
812
- * **Components**: The UI elements available to the agent for creating rich interactive
813
- * experiences (text, buttons, images, cards, etc.).
814
- *
815
- * ## Implementation Requirements
816
- *
817
- * To create a functional chat interface, you must:
818
- * 1. Implement the MessageHandler to display agent messages to users
819
- * 2. Maintain an accurate transcript of the conversation
820
- * 3. Provide the available UI components (typically includes DefaultComponents)
821
- * 4. Optional: Override onExecutionDone() to handle execution completion
822
- *
823
- * ## Basic Implementation
824
- *
825
- * ```typescript
826
- * import { Chat, DefaultComponents, isComponent } from 'llmz'
827
- *
828
- * class MyChat extends Chat {
829
- * private messages: Array<{role: 'user' | 'assistant', content: string}> = []
830
- *
831
- * constructor() {
832
- * super({
833
- * // Handle agent messages - this is called for every agent output
834
- * handler: async (input) => {
835
- * if (isComponent(input, DefaultComponents.Text)) {
836
- * const text = input.children.join('')
837
- * console.log('Agent:', text)
838
- * this.messages.push({ role: 'assistant', content: text })
839
- * } else if (isComponent(input, DefaultComponents.Button)) {
840
- * console.log('Button:', input.props.label)
841
- * }
842
- * },
843
- *
844
- * // Provide available components - agent can use these in generated code
845
- * components: [DefaultComponents.Text, DefaultComponents.Button],
846
- *
847
- * // Return current transcript - evaluated at each iteration
848
- * transcript: () => this.messages,
849
- * })
850
- * }
851
- *
852
- * // Add user message to transcript
853
- * addUserMessage(content: string) {
854
- * this.messages.push({ role: 'user', content })
855
- * }
856
- * }
857
- *
858
- * // Usage
859
- * const chat = new MyChat()
860
- * chat.addUserMessage('Hello!')
861
- *
862
- * const result = await execute({
863
- * instructions: 'You are a helpful assistant',
864
- * chat, // Enable chat mode
865
- * client,
866
- * })
867
- * ```
868
- *
869
- * ## Advanced Implementation (CLIChat Example)
870
- *
871
- * ```typescript
872
- * import { Chat, DefaultComponents, ListenExit } from 'llmz'
873
- *
874
- * class CLIChat extends Chat {
875
- * public transcript: Array<{role: 'user' | 'assistant', content: string}> = []
876
- * private buttons: string[] = []
877
- * public result?: ExecutionResult
878
- *
879
- * constructor() {
880
- * super({
881
- * // Dynamic component list with custom renderers
882
- * components: () => [
883
- * DefaultComponents.Text,
884
- * DefaultComponents.Button,
885
- * ...this.customComponents
886
- * ],
887
- *
888
- * // Dynamic transcript access
889
- * transcript: () => this.transcript,
890
- *
891
- * // Sophisticated message handling
892
- * handler: async (input) => {
893
- * if (isComponent(input, DefaultComponents.Text)) {
894
- * const text = input.children.join('')
895
- * console.log('🤖 Agent:', text)
896
- * this.transcript.push({ role: 'assistant', content: text })
897
- * } else if (isComponent(input, DefaultComponents.Button)) {
898
- * this.buttons.push(input.props.label)
899
- * }
900
- * },
901
- * })
902
- * }
903
- *
904
- * // Handle execution completion
905
- * onExecutionDone(result: ExecutionResult) {
906
- * this.result = result
907
- * }
908
- *
909
- * // Check if agent is waiting for user input
910
- * isWaitingForInput(): boolean {
911
- * return this.result?.is(ListenExit) ?? false
912
- * }
913
- *
914
- * // Conversation loop
915
- * async iterate(): Promise<boolean> {
916
- * if (this.isWaitingForInput()) {
917
- * const userInput = await this.promptUser()
918
- * this.transcript.push({ role: 'user', content: userInput })
919
- * return true // Continue conversation
920
- * }
921
- * return false // End conversation
922
- * }
923
- * }
924
- * ```
925
- *
926
- * ## Component System
927
- *
928
- * The agent generates JSX code using available components:
929
- *
930
- * ```typescript
931
- * // Agent generates this TSX code:
932
- * yield <Text>Welcome! Choose an option:</Text>
933
- * yield <Button action="postback" label="Get Help" value="help" />
934
- * yield <Button action="postback" label="Contact Sales" value="sales" />
935
- *
936
- * // Your handler receives these as RenderedComponent objects
937
- * ```
938
- *
939
- * ## Transcript Management
940
- *
941
- * The transcript is critical for agent context and must be kept up-to-date:
942
- *
943
- * ```typescript
944
- * // ❌ Bad - static transcript
945
- * transcript: [{ role: 'user', content: 'Hello' }]
946
- *
947
- * // ✅ Good - dynamic transcript that reflects current state
948
- * transcript: () => this.messages
949
- *
950
- * // The transcript is evaluated at each iteration, so the agent
951
- * // always sees the current conversation state
952
- * ```
953
- *
954
- * ## Custom Components
955
- *
956
- * Extend the UI with custom components for your specific use case:
957
- *
958
- * ```typescript
959
- * import { Component } from 'llmz'
960
- *
961
- * const ProductCard = new Component({
962
- * type: 'leaf',
963
- * name: 'ProductCard',
964
- * leaf: {
965
- * props: z.object({
966
- * name: z.string(),
967
- * price: z.number(),
968
- * imageUrl: z.string(),
969
- * })
970
- * }
971
- * })
972
- *
973
- * class ShoppingChat extends Chat {
974
- * constructor() {
975
- * super({
976
- * components: [
977
- * ...DefaultComponents,
978
- * ProductCard, // Add custom component
979
- * ],
980
- * handler: async (input) => {
981
- * if (isComponent(input, ProductCard)) {
982
- * // Handle custom component rendering
983
- * this.renderProduct(input.props)
984
- * }
985
- * // ... handle other components
986
- * },
987
- * })
988
- * }
989
- * }
990
- * ```
991
- *
992
- * @see {@link DefaultComponents} For standard UI components
993
- * @see {@link https://github.com/botpress/botpress/blob/master/packages/llmz/examples/utils/cli-chat.ts} Complete CLIChat implementation
994
- */
995
- var Chat = class {
996
- handler;
997
- onMessageDelta;
998
- transcript;
999
- components;
1000
- /**
1001
- * Creates a new Chat instance.
1002
- *
1003
- * @param props - Chat configuration
1004
- * @param props.handler - Function to handle agent messages (called for every agent output)
1005
- * @param props.components - Available UI components (static array or dynamic function)
1006
- * @param props.transcript - Conversation history (static array or dynamic function, defaults to empty)
1007
- *
1008
- * @example
1009
- * ```typescript
1010
- * // Basic chat with static configuration
1011
- * const chat = new Chat({
1012
- * handler: async (input) => {
1013
- * if (isComponent(input, DefaultComponents.Text)) {
1014
- * console.log('Agent:', input.children.join(''))
1015
- * }
1016
- * },
1017
- * components: [DefaultComponents.Text, DefaultComponents.Button],
1018
- * transcript: [
1019
- * { role: 'user', content: 'Hello', timestamp: Date.now() }
1020
- * ],
1021
- * })
1022
- * ```
1023
- *
1024
- * @example
1025
- * ```typescript
1026
- * // Dynamic chat with functions for real-time updates
1027
- * class MyChat extends Chat {
1028
- * private messages: Transcript.Message[] = []
1029
- *
1030
- * constructor() {
1031
- * super({
1032
- * handler: (input) => this.handleMessage(input),
1033
- *
1034
- * // Dynamic components - can change during execution
1035
- * components: () => [
1036
- * DefaultComponents.Text,
1037
- * DefaultComponents.Button,
1038
- * ...this.getCustomComponents()
1039
- * ],
1040
- *
1041
- * // Dynamic transcript - always reflects current state
1042
- * transcript: () => this.messages,
1043
- * })
1044
- * }
1045
- * }
1046
- * ```
1047
- */
1048
- constructor(props) {
1049
- this.handler = props.handler;
1050
- this.onMessageDelta = props.onMessageDelta;
1051
- this.components = props.components;
1052
- this.transcript = props.transcript || [];
1053
- }
1054
- /**
1055
- * Called when an execution cycle completes, regardless of the outcome.
1056
- *
1057
- * Override this method to handle execution results, manage conversation flow,
1058
- * or perform cleanup tasks. This is called after each `execute()` call completes,
1059
- * whether it succeeds, fails, or is interrupted.
1060
- *
1061
- * @param result - The execution result containing status, iterations, and exit information
1062
- *
1063
- * @example
1064
- * ```typescript
1065
- * class MyChat extends Chat {
1066
- * public result?: ExecutionResult
1067
- *
1068
- * onExecutionDone(result: ExecutionResult) {
1069
- * // Store result for conversation flow control
1070
- * this.result = result
1071
- *
1072
- * // Handle different result types
1073
- * if (result.isSuccess()) {
1074
- * console.log('✅ Execution completed successfully')
1075
- * console.log('Exit:', result.output.exit_name)
1076
- * } else if (result.isError()) {
1077
- * console.error('❌ Execution failed:', result.output.error)
1078
- * } else if (result.isInterrupted()) {
1079
- * console.log('⏸️ Execution interrupted (partial result)')
1080
- * }
1081
- * }
1082
- *
1083
- * // Use stored result for conversation flow
1084
- * isWaitingForInput(): boolean {
1085
- * return this.result?.is(ListenExit) ?? false
1086
- * }
1087
- * }
1088
- * ```
1089
- *
1090
- * @example
1091
- * ```typescript
1092
- * // CLIChat implementation example
1093
- * class CLIChat extends Chat {
1094
- * public status?: IterationStatus
1095
- * public result?: ExecutionResult
1096
- *
1097
- * onExecutionDone(result: ExecutionResult) {
1098
- * this.result = result
1099
- * this.status = result.iterations.at(-1)?.status
1100
- * }
1101
- *
1102
- * // Check if agent exited with specific exit type
1103
- * hasExitedWith<R>(exit: Exit<R>): boolean {
1104
- * return this.status?.type === 'exit_success' &&
1105
- * this.status.exit_success.exit_name === exit.name
1106
- * }
1107
- * }
1108
- * ```
1109
- */
1110
- onExecutionDone(_result) {}
479
+ //#region src/chat/component.default.ts
480
+ const buttonProps = z.object({
481
+ action: z.enum([
482
+ "say",
483
+ "url",
484
+ "postback"
485
+ ]).default("say").describe("The action to perform when the button is clicked: say, url, or postback"),
486
+ label: z.string().min(1).max(250).describe("The text displayed on the button (1–250 characters)"),
487
+ value: z.string().optional().describe("The postback value. Required when action is postback"),
488
+ url: z.string().optional().describe("The URL to open. Required when action is url")
489
+ }).strict();
490
+ const imageProps = z.object({
491
+ url: z.string().describe("The URL of the image (must be valid)"),
492
+ alt: z.string().optional().describe("Alternative text describing the image")
493
+ }).strict();
494
+ const cardProps = z.object({
495
+ title: z.string().min(1).max(250).describe("Title text (1–250 characters)"),
496
+ subtitle: z.string().optional().describe("Optional subtitle for the card"),
497
+ text: z.string().optional().describe("Optional Markdown text for the card"),
498
+ image: imageProps.optional().describe("Optional image for the card; use a known URL"),
499
+ buttons: z.array(buttonProps).max(5).optional().describe("Up to 5 actions for the card")
500
+ }).strict();
501
+ const DefaultComponents = {
502
+ Buttons: new Component({
503
+ name: "buttons",
504
+ description: "Offer quick actions or choices after a message. Buttons appear together in array order.",
505
+ props: z.array(buttonProps).min(1)
506
+ }),
507
+ Image: new Component({
508
+ name: "image",
509
+ description: "Display an image using a known URL from the user or tool results; never invent an image URL.",
510
+ props: imageProps
511
+ }),
512
+ File: new Component({
513
+ name: "file",
514
+ description: "Send a downloadable file to the user.",
515
+ props: z.object({
516
+ url: z.string().describe("The URL of the file (must be valid)"),
517
+ name: z.string().optional().describe("The display name of the file")
518
+ }).strict()
519
+ }),
520
+ Video: new Component({
521
+ name: "video",
522
+ description: "Embed a video from a URL.",
523
+ props: z.object({
524
+ url: z.string().describe("The URL of the video (must be valid)"),
525
+ title: z.string().optional().describe("Title for the video")
526
+ }).strict()
527
+ }),
528
+ Audio: new Component({
529
+ name: "audio",
530
+ description: "Play an audio clip from a URL.",
531
+ props: z.object({
532
+ url: z.string().describe("The URL of the audio clip (must be valid)"),
533
+ title: z.string().optional().describe("Title for the audio clip")
534
+ }).strict()
535
+ }),
536
+ Card: new Component({
537
+ name: "card",
538
+ description: "Present one item with a title, optional subtitle, Markdown text, image, and buttons.",
539
+ props: cardProps
540
+ }),
541
+ Carousel: new Component({
542
+ name: "carousel",
543
+ description: "Display several comparable items as a horizontally scrollable collection of cards.",
544
+ props: z.object({ cards: z.array(cardProps).min(1).max(10).describe("1–10 cards in display order, each with its own content and actions") }).strict()
545
+ })
1111
546
  };
1112
547
  //#endregion
1113
- //#region src/message-stream/replayable.ts
1114
- /**
1115
- * Wraps an async iterable so it can be iterated multiple times: chunks pulled
1116
- * from the source are cached, and every iteration replays the cache before
1117
- * pulling new chunks. Concurrent iterations are safe — pulls on the underlying
1118
- * source are serialized. If the source fails, the failure is cached too:
1119
- * every iteration replays the chunks received before the failure, then
1120
- * rethrows the source error.
1121
- */
1122
- var ReplayableAsyncIterable = class {
1123
- _source;
1124
- _chunks = [];
1125
- _done = false;
1126
- _failed = false;
1127
- _error;
1128
- _lock = Promise.resolve();
1129
- constructor(source) {
1130
- this._source = source[Symbol.asyncIterator]();
1131
- }
1132
- /** True once the underlying source has been fully consumed (or has failed). */
1133
- get done() {
1134
- return this._done;
1135
- }
1136
- /** The chunks pulled from the source so far. */
1137
- get chunks() {
1138
- return [...this._chunks];
1139
- }
1140
- async *[Symbol.asyncIterator]() {
1141
- let index = 0;
1142
- while (true) if (index < this._chunks.length) yield this._chunks[index++];
1143
- else if (this._failed) throw this._error;
1144
- else if (this._done) return;
1145
- else await this._pull();
1146
- }
1147
- /** Consumes the entire source and returns all chunks. */
1148
- async collect() {
1149
- for await (const _ of this);
1150
- return this.chunks;
1151
- }
1152
- _pull() {
1153
- const next = this._lock.then(async () => {
1154
- if (this._done) return;
1155
- let result;
1156
- try {
1157
- result = await this._source.next();
1158
- } catch (thrown) {
1159
- this._done = true;
1160
- this._failed = true;
1161
- this._error = thrown;
1162
- throw thrown;
1163
- }
1164
- if (result.done) this._done = true;
1165
- else this._chunks.push(result.value);
1166
- });
1167
- this._lock = next.catch(() => {});
1168
- return next;
1169
- }
1170
- };
1171
- /** Drains a string iterable into a single string. */
1172
- const collectText = async (iterable) => {
1173
- let text = "";
1174
- for await (const chunk of iterable) text += chunk;
1175
- return text;
1176
- };
1177
- //#endregion
1178
- //#region src/message-stream/stream.ts
1179
- var BaseResponse = class {
1180
- action;
1181
- item;
1182
- constructor(action, item) {
1183
- this.action = action;
1184
- this.item = item;
1185
- }
1186
- get diagnostics() {
1187
- return this.item.diagnostics;
1188
- }
1189
- };
1190
- /** `■send=<component> { props? }` followed by an optional streaming body. */
1191
- var SendResponse = class extends BaseResponse {
1192
- content;
1193
- constructor(item, content) {
1194
- super("send", item);
1195
- this.content = content;
1196
- }
1197
- get component() {
1198
- return this.item.name;
1199
- }
1200
- get props() {
1201
- return this.item.props;
1202
- }
1203
- static formatToText(component, props, body) {
1204
- const header = `■send=${component}${props && Object.keys(props).length ? ` ${JSON.stringify(props)}` : ""}`;
1205
- return body ? `${header}\n${body}` : header;
1206
- }
1207
- };
1208
- /** `■run` followed by streaming code. */
1209
- var RunResponse = class extends BaseResponse {
1210
- code;
1211
- constructor(item, code) {
1212
- super("run", item);
1213
- this.code = code;
1214
- }
1215
- static formatToText(code) {
1216
- return `■run\n${code}`;
1217
- }
1218
- };
1219
- /** `■next=<name> { props? }` — hands control to an exit (e.g. listen) with optional props. */
1220
- var NextResponse = class extends BaseResponse {
1221
- constructor(item) {
1222
- super("next", item);
1223
- }
1224
- get name() {
1225
- return this.item.name;
1226
- }
1227
- get props() {
1228
- return this.item.props;
1229
- }
1230
- static formatToText(name, props) {
1231
- return `■next=${name}${props && Object.keys(props).length ? ` ${JSON.stringify(props)}` : ""}`;
1232
- }
1233
- };
1234
- /**
1235
- * Pulls transport chunks through the parser on demand and hands out events one
1236
- * at a time. Shared by the main response loop and by body streams; pulls are
1237
- * serialized so interleaved consumers cannot race the source iterator.
1238
- */
1239
- var EventPump = class {
1240
- _iterator;
1241
- _parser;
1242
- _queue = [];
1243
- _sourceDone = false;
1244
- _lock = Promise.resolve();
1245
- constructor(stream, parser) {
1246
- this._iterator = stream[Symbol.asyncIterator]();
1247
- this._parser = parser;
1248
- }
1249
- next() {
1250
- const next = this._lock.then(() => this._next());
1251
- this._lock = next.catch(() => {});
1252
- return next;
1253
- }
1254
- unshift(event) {
1255
- this._queue.unshift(event);
1256
- }
1257
- async _next() {
1258
- while (this._queue.length === 0) {
1259
- if (this._sourceDone) return;
1260
- let result;
1261
- try {
1262
- result = await this._iterator.next();
1263
- } catch {
1264
- this._sourceDone = true;
1265
- this._queue.push(...this._parser.finish("interrupted"));
1266
- continue;
1267
- }
1268
- if (result.done) {
1269
- this._sourceDone = true;
1270
- this._queue.push(...this._parser.finish());
1271
- } else this._queue.push(...this._parser.push(result.value));
1272
- }
1273
- return this._queue.shift();
1274
- }
1275
- };
1276
- /**
1277
- * Parses a raw LLM text stream into typed responses.
1278
- *
1279
- * `send` and `run` responses are yielded as soon as their header is parsed —
1280
- * while their body is still streaming — with the body exposed as a replayable
1281
- * async iterable. `next` responses are yielded once complete.
1282
- *
1283
- * The body streams are pull-based: consuming them drives the underlying
1284
- * transport. Requesting the next response first drains the previous body into
1285
- * its replay cache, so it can always be read later.
1286
- */
1287
- function parseStream(stream, options) {
1288
- return parseResponses(stream, options);
1289
- }
1290
- /** Parses a complete text (convenience wrapper over {@link parseStream}). */
1291
- function parseText(text, options) {
1292
- return parseResponses((async function* () {
1293
- yield text;
1294
- })(), options);
1295
- }
1296
- async function* parseResponses(stream, options) {
1297
- const pump = new EventPump(stream, new StreamingMessageParser(options));
1298
- let activeBody;
1299
- while (true) {
1300
- if (activeBody) {
1301
- await activeBody.collect();
1302
- activeBody = void 0;
1303
- }
1304
- const event = await pump.next();
1305
- if (!event) return;
1306
- if (event.type === "item-ready" && (event.item.kind === "send" || event.item.kind === "run")) {
1307
- const body = new ReplayableAsyncIterable(bodyStream(pump, event.item.id));
1308
- activeBody = body;
1309
- yield event.item.kind === "send" ? new SendResponse(event.item, body) : new RunResponse(event.item, body);
1310
- continue;
1311
- }
1312
- if (event.type === "item-complete" && event.item.kind === "next") {
1313
- yield new NextResponse(event.item);
1314
- continue;
1315
- }
1316
- }
1317
- }
1318
- async function* bodyStream(pump, itemId) {
1319
- while (true) {
1320
- const event = await pump.next();
1321
- if (!event) return;
1322
- if (event.type === "body-delta" && event.itemId === itemId) {
1323
- yield event.delta;
1324
- continue;
1325
- }
1326
- if (event.type === "body-start" && event.itemId === itemId) continue;
1327
- if (event.type === "diagnostic") continue;
1328
- if (event.type === "item-complete" && event.item.id === itemId) return;
1329
- pump.unshift(event);
1330
- return;
1331
- }
1332
- }
1333
- //#endregion
1334
- //#region src/message-stream/normalizer.ts
1335
- const EMPTY_PROPS_SCHEMA = {
1336
- type: "object",
1337
- properties: {},
1338
- additionalProperties: false
1339
- };
1340
- const normalizeComponentName = (name) => name.trim().toLowerCase();
1341
- function normalizeComponentDefinition(definition) {
1342
- const name = normalizeComponentName(definition.name ?? "");
1343
- if (!NAME_REGEX.test(name)) throw new Error(`Invalid component name "${definition.name}". Component names must be lowercase ([a-z][a-z0-9_-]*).`);
1344
- return {
1345
- name,
1346
- description: definition.description,
1347
- propsJsonSchema: normalizePropsSchema(definition.props, name),
1348
- body: definition.body ? {
1349
- format: definition.body.type,
1350
- description: definition.body.description,
1351
- required: definition.body.required ?? false
1352
- } : void 0,
1353
- generation: definition.generation
1354
- };
1355
- }
1356
- function normalizePropsSchema(props, name) {
1357
- if (props === void 0) return EMPTY_PROPS_SCHEMA;
1358
- if (isZuiSchema(props)) try {
1359
- return transforms.toJSONSchema(props);
1360
- } catch {
1361
- return transforms.toJSONSchemaLegacy(props);
1362
- }
1363
- if (isJsonSchema(props)) return props;
1364
- throw new Error(`Invalid props schema for "${name}". Expected a ZUI/Zod object schema or a JSON schema, but got type "${typeof props}".`);
1365
- }
1366
- //#endregion
1367
- //#region src/message-stream/sanitize.ts
1368
- /**
1369
- * The protocol has no escaping mechanism by design. Any untrusted text that is
1370
- * inserted into model context (user messages, tool results, documents) must be
1371
- * sanitized so it cannot inject protocol blocks.
1372
- */
1373
- const sanitizeMessageText = (value, options = {}) => value.replaceAll("■", options.markerReplacement ?? "▪");
1374
- //#endregion
1375
548
  //#region src/index.ts
1376
549
  const utils = {
1377
550
  toValidObjectName,
1378
- toValidFunctionName,
1379
- wrapContent,
1380
- truncateWrappedContent,
1381
- stripTruncationTags
551
+ toValidFunctionName
1382
552
  };
1383
553
  /**
1384
554
  * Executes an LLMz agent in either Chat Mode or Worker Mode.
1385
555
  *
1386
- * LLMz is a code-first AI agent framework that generates and runs TypeScript code
1387
- * in a sandbox rather than using traditional JSON tool calling. This enables complex
1388
- * logic, multi-tool orchestration, and native LLM thinking via comments and code structure.
556
+ * LLMz generates and runs JavaScript in a sandbox through the native run_javascript
557
+ * tool. Assistant text streams normally; JavaScript returns decisions to present
558
+ * rich messages, inspect results, or complete through a typed exit.
1389
559
  *
1390
560
  * @param props - Configuration object for the execution
1391
561
  * @param props.client - Botpress Client or Cognitive Client instance for LLM generation
1392
562
  * @param props.instructions - System prompt/instructions for the LLM (static string or dynamic function)
1393
- * @param props.examples - Optional labeled few-shot examples (static array or dynamic function)
1394
563
  * @param props.chat - Optional Chat instance to enable Chat Mode with user interaction
1395
564
  * @param props.tools - Array of Tool instances available to the agent (static or dynamic)
1396
565
  * @param props.objects - Array of ObjectInstance for namespaced tools and variables (static or dynamic)
1397
566
  * @param props.exits - Array of Exit definitions for structured completion (static or dynamic)
1398
- * @param props.snapshot - Optional Snapshot to resume paused execution
567
+ * @param props.session - Conversation state; append input before execution and persist it between executions
1399
568
  * @param props.signal - Optional AbortSignal to cancel execution
1400
569
  * @param props.model - Optional model name (or array or models to use as fallback) (static or dynamic function)
1401
570
  * @param props.temperature - Optional temperature value (static or dynamic function)
@@ -1439,7 +608,7 @@ const utils = {
1439
608
  * // With dynamic instructions and hooks
1440
609
  * const result = await execute({
1441
610
  * client: cognitiveClient,
1442
- * instructions: (ctx) => `Process ${ctx.variables.dataCount} records`,
611
+ * instructions: (ctx) => `Process ${ctx.session.memory.variables.dataCount} records`,
1443
612
  * tools: async (ctx) => await getContextualTools(ctx),
1444
613
  * model: 'best',
1445
614
  * temperature: 0.1,
@@ -1449,7 +618,7 @@ const utils = {
1449
618
  * })
1450
619
  */
1451
620
  const execute = async (props) => {
1452
- const { executeContext } = await import("./execute-Aw4cbIx-.js");
621
+ const { executeContext } = await import("./execute-BYI_U5sR.js");
1453
622
  return executeContext(props);
1454
623
  };
1455
624
  /**
@@ -1458,16 +627,14 @@ const execute = async (props) => {
1458
627
  * It's recommended to call this function at the beginning of your application without awaiting it (void init())
1459
628
  */
1460
629
  const init = async () => {
1461
- await import("./execute-Aw4cbIx-.js");
1462
- await import("./component-Dq7ZLdvy.js").then((n) => n.r);
1463
- await import("./tool-Bv8N4IPj.js").then((n) => n.n);
1464
- await import("./exit-CDdxDBRT.js").then((n) => n.n);
1465
- await import("./jsx-B0iYyvfr.js").then((n) => n.i);
1466
- await import("./vm-BLsHw1da.js");
1467
- await import("./utils-UBeAFeEI.js").then((n) => n.h);
1468
- await import("./truncator-DZqEqnpD.js").then((n) => n.r);
1469
- await import("./typings-CrBa7Tyy.js").then((n) => n.n);
1470
- await import("./dual-modes-Cy0_W4O2.js").then((n) => n.n);
630
+ await import("./execute-BYI_U5sR.js");
631
+ await import("./component-C27qu6Zv.js").then((n) => n.r);
632
+ await import("./tool--gK91eez.js").then((n) => n.n);
633
+ await import("./exit-CPNk3vbz.js").then((n) => n.n);
634
+ await import("./vm-8jxt8PTK.js");
635
+ await import("./utils-BOFzb8Ok.js").then((n) => n.m);
636
+ await import("./typings-D9_aC8aq.js").then((n) => n.r);
637
+ await import("./native-DvTH9vFe.js").then((n) => n.n);
1471
638
  };
1472
639
  //#endregion
1473
- export { BaseResponse, Chat, CitationsManager, Component, ComponentRegistry, DefaultComponents, DefaultExit, ErrorExecutionResult, Example, ExecutionResult, Exit, ListenExit, LoopExceededError, MARKER, NAME_REGEX, NextResponse, ObjectInstance, PartialExecutionResult, ReplayableAsyncIterable, RunResponse, SendResponse, Snapshot, SnapshotSignal, StreamingMessageParser, SuccessExecutionResult, ThinkExit, ThinkSignal, Tool, _CustomModelClient, assertValidComponent, collectText, configureQuickJS, configureTokenizer, execute, generateInstructions, getValue, init, isAnyComponent, isComponent, normalizeComponentDefinition, normalizeComponentName, normalizePropsSchema, parseExit, parseStream, parseText, sanitizeMessageText, tryParseJson, utils, validateComponent, validateProps, version };
640
+ export { AssignmentError, Chat, CitationsManager, CodeExecutionError, CodeFormattingError, CognitiveError, CompactionError, Component, ComponentInputError, DefaultComponents, DefaultExit, DeliveryError, ErrorExecutionResult, ExecutionAbortedError, ExecutionResult, Exit, ExitInputError, HookError, HostOperationError, InternalError, InvalidCodeError, InvalidComponentError, InvalidConfigurationError, InvalidEventError, InvalidExitError, InvalidMessageError, InvalidObjectError, InvalidSessionError, InvalidToolError, LLMzError, ListenExit, LoopExceededError, Memory, MemoryCapacityError, MemoryValueError, NativeProtocolError, ObjectInstance, ObjectPropertyError, ReservedIdentifierError, Session, SessionStateError, SuccessExecutionResult, ThinkSignal, TokenOverflowError, Tool, ToolExecutionError, ToolInputError, UnknownComponentError, UnknownExitError, UnknownToolError, _CustomModelClient, assertValidComponent, configureQuickJS, configureTokenizer, createInspector, execute, getValue, init, inspect, isAnyComponent, isComponent, isCriticalError, isLLMzError, truncate, utils, version };