llmz 0.9.0 → 1.0.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 (238) hide show
  1. package/DOCS.md +232 -1794
  2. package/ERRORS.md +101 -0
  3. package/README.md +96 -582
  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-CMFoCHyu.cjs +649 -0
  16. package/dist/component-DncqP4fB.js +614 -0
  17. package/dist/context.d.ts +71 -378
  18. package/dist/custom-client-C-WXvLD9.js +1655 -0
  19. package/dist/custom-client-Cgt9_0r1.cjs +1732 -0
  20. package/dist/custom-client.d.ts +12 -2
  21. package/dist/errors/catalog.d.ts +294 -0
  22. package/dist/errors/hooks.d.ts +2 -0
  23. package/dist/errors-C6ppQUZX.cjs +893 -0
  24. package/dist/errors-Crk5P8jo.js +636 -0
  25. package/dist/errors.d.ts +24 -36
  26. package/dist/execute-CiYvPs5Q.js +2061 -0
  27. package/dist/execute-DTTfacsi.cjs +2062 -0
  28. package/dist/{exit-DUM96DN1.cjs → exit-BOtKWPuT.cjs} +38 -28
  29. package/dist/{exit-CDdxDBRT.js → exit-DMPwCSba.js} +37 -27
  30. package/dist/exit.d.ts +19 -16
  31. package/dist/index.cjs +177 -1237
  32. package/dist/index.d.ts +25 -28
  33. package/dist/index.js +137 -1213
  34. package/dist/index.workerd.js +8974 -11145
  35. package/dist/inspect.d.ts +18 -4
  36. package/dist/inspection.d.ts +40 -0
  37. package/dist/native-0bq5ATZM.cjs +212 -0
  38. package/dist/native-n_718Z-T.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 -101
  42. package/dist/quickjs-variant-21IO97PF.cjs +1080 -0
  43. package/dist/quickjs-variant-CtuGagsb.js +985 -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-diagnostics.d.ts +11 -0
  48. package/dist/runtime/execution-report.d.ts +51 -0
  49. package/dist/runtime/fixtures/chat.d.ts +8 -0
  50. package/dist/runtime/fixtures/long-search.d.ts +1 -1
  51. package/dist/runtime/fixtures/native-client.d.ts +33 -0
  52. package/dist/runtime/fixtures/protocol-languages.d.ts +1 -1
  53. package/dist/runtime/forced-inspection.d.ts +13 -0
  54. package/dist/runtime/forced-inspection.test.d.ts +1 -0
  55. package/dist/runtime/generate.d.ts +23 -20
  56. package/dist/runtime/generate.test.d.ts +1 -0
  57. package/dist/runtime/hook-provenance.test.d.ts +1 -0
  58. package/dist/runtime/inspection-hook.test.d.ts +1 -0
  59. package/dist/runtime/inspection-values.d.ts +14 -0
  60. package/dist/runtime/inspection-values.test.d.ts +1 -0
  61. package/dist/runtime/interruption-control-flow.test.d.ts +1 -0
  62. package/dist/runtime/interruption-settings.test.d.ts +1 -0
  63. package/dist/runtime/javascript-api.d.ts +62 -0
  64. package/dist/runtime/javascript-api.test.d.ts +1 -0
  65. package/dist/runtime/native-review.test.d.ts +1 -0
  66. package/dist/runtime/native-tools.d.ts +18 -0
  67. package/dist/runtime/native-tools.test.d.ts +1 -0
  68. package/dist/runtime/object-memory.test.d.ts +1 -0
  69. package/dist/runtime/single-tool.test.d.ts +1 -0
  70. package/dist/runtime/think-signal.test.d.ts +1 -0
  71. package/dist/runtime/token-budget.d.ts +22 -0
  72. package/dist/runtime/token-budget.test.d.ts +1 -0
  73. package/dist/runtime/tool-wrapper.d.ts +6 -5
  74. package/dist/runtime/traces.test.d.ts +1 -0
  75. package/dist/runtime/truncation.test.d.ts +1 -0
  76. package/dist/runtime/types.d.ts +47 -31
  77. package/dist/runtime/variable-recovery.test.d.ts +1 -0
  78. package/dist/runtime/vm-context.d.ts +6 -1
  79. package/dist/runtime/worker-completion.test.d.ts +1 -0
  80. package/dist/runtime-names.d.ts +4 -0
  81. package/dist/schema-CXlnbb3n.cjs +68 -0
  82. package/dist/schema-GE4ISPCR.js +45 -0
  83. package/dist/schema.d.ts +10 -0
  84. package/dist/schema.test.d.ts +1 -0
  85. package/dist/session/compactor.d.ts +51 -0
  86. package/dist/session/compactor.test.d.ts +1 -0
  87. package/dist/session/history.d.ts +36 -0
  88. package/dist/session/history.test.d.ts +1 -0
  89. package/dist/session/json.d.ts +3 -0
  90. package/dist/session/json.test.d.ts +1 -0
  91. package/dist/session/memory-codec.d.ts +9 -0
  92. package/dist/session/memory-codec.test.d.ts +1 -0
  93. package/dist/session/memory-render.d.ts +15 -0
  94. package/dist/session/memory-render.test.d.ts +1 -0
  95. package/dist/session/memory.d.ts +112 -0
  96. package/dist/session/memory.test.d.ts +1 -0
  97. package/dist/session/messages.d.ts +19 -0
  98. package/dist/session/messages.test.d.ts +1 -0
  99. package/dist/session/serialization.d.ts +36 -0
  100. package/dist/session/serialization.test.d.ts +1 -0
  101. package/dist/session/session-memory.test.d.ts +1 -0
  102. package/dist/session/session.d.ts +121 -0
  103. package/dist/session/session.test.d.ts +1 -0
  104. package/dist/session/speaker.test.d.ts +1 -0
  105. package/dist/{transcript.d.ts → session/transcript.d.ts} +4 -8
  106. package/dist/session/transcript.test.d.ts +1 -0
  107. package/dist/{tool-Bv8N4IPj.js → tool-DstssiAs.js} +144 -92
  108. package/dist/{tool-Dy6AJpJH.cjs → tool-_wK9hQOb.cjs} +146 -94
  109. package/dist/tool.d.ts +25 -17
  110. package/dist/truncate-BEKbdo3t.js +79 -0
  111. package/dist/truncate-uomAMGPs.cjs +102 -0
  112. package/dist/truncate.d.ts +24 -0
  113. package/dist/truncate.test.d.ts +1 -0
  114. package/dist/types.d.ts +33 -9
  115. package/dist/{typings-3lsqCbkn.cjs → typings-BA_XxAcY.cjs} +38 -193
  116. package/dist/{typings-CrBa7Tyy.js → typings-BEVDvtuk.js} +38 -175
  117. package/dist/typings-formatter.d.ts +1 -1
  118. package/dist/typings.d.ts +3 -0
  119. package/dist/{uniq-BYQ7GWwb.js → uniq-DfUeSNaX.js} +2 -2
  120. package/dist/{uniq-G872RWmE.cjs → uniq-DiXgysNV.cjs} +6 -18
  121. package/dist/{_baseIteratee-P_firB7b.js → utils-BOFzb8Ok.js} +1134 -16
  122. package/dist/{_baseIteratee-CF4qP2a8.cjs → utils-CTlsXvdj.cjs} +1281 -84
  123. package/dist/vm/drivers/node.d.ts +1 -1
  124. package/dist/vm/drivers/quickjs.d.ts +1 -1
  125. package/dist/vm/errors.d.ts +4 -4
  126. package/dist/vm/index.d.ts +3 -4
  127. package/dist/vm/instrument.d.ts +14 -6
  128. package/dist/vm/member-proxy.d.ts +4 -0
  129. package/dist/vm/member-proxy.test.d.ts +1 -0
  130. package/dist/vm/memory.test.d.ts +1 -0
  131. package/dist/vm/return-semantics.test.d.ts +1 -0
  132. package/dist/vm/types.d.ts +20 -3
  133. package/dist/{vm-BLsHw1da.js → vm-C7SfutHn.js} +1187 -180
  134. package/dist/{vm-D6s1zF6M.cjs → vm-gmekHc0i.cjs} +1221 -207
  135. package/package.json +13 -6
  136. package/dist/_baseForOwn-BfWDTL8L.cjs +0 -53
  137. package/dist/_baseForOwn-CFhWe_W6.js +0 -48
  138. package/dist/_getPrototype-CG7Dxrrz.js +0 -6
  139. package/dist/_getPrototype-DQDlNVVM.cjs +0 -10
  140. package/dist/_overArg-C5Hy7oCi.cjs +0 -196
  141. package/dist/_overArg-CRYbj1NH.js +0 -155
  142. package/dist/chat.d.ts +0 -401
  143. package/dist/common-BlRFtdf2.js +0 -807
  144. package/dist/common-BnvrDnIT.cjs +0 -860
  145. package/dist/compiler/plugins/track-tool-calls.d.ts +0 -33
  146. package/dist/compiler-C-OI9sim.cjs +0 -547
  147. package/dist/compiler-CW1VjQsn.js +0 -473
  148. package/dist/component-C6Agl2ns.cjs +0 -73
  149. package/dist/component-DGG7d_Mz.js +0 -44
  150. package/dist/component.d.ts +0 -88
  151. package/dist/component.default.d.ts +0 -278
  152. package/dist/custom-client-ChuZ63zp.js +0 -2658
  153. package/dist/custom-client-DAsGRnYc.cjs +0 -2729
  154. package/dist/dual-modes-DDkoCp3R.js +0 -3006
  155. package/dist/dual-modes-DPXiuvNe.cjs +0 -3090
  156. package/dist/errors-C962uJdS.cjs +0 -220
  157. package/dist/errors-Cg1G0Awu.js +0 -161
  158. package/dist/example-format.d.ts +0 -8
  159. package/dist/example.d.ts +0 -45
  160. package/dist/execute-BWcdv9so.js +0 -1059
  161. package/dist/execute-DM2-7y86.cjs +0 -1060
  162. package/dist/exit-parser.d.ts +0 -39
  163. package/dist/handlers.d.ts +0 -10
  164. package/dist/hoist.d.ts +0 -2
  165. package/dist/isEmpty-BhJRCqIF.js +0 -52
  166. package/dist/isEmpty-LY533Wmh.cjs +0 -57
  167. package/dist/isPlainObject-CSxXVKCk.cjs +0 -56
  168. package/dist/isPlainObject-D39AzPO2.js +0 -51
  169. package/dist/jsx-CIgdGGVs.js +0 -52
  170. package/dist/jsx-owqxrquU.cjs +0 -75
  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 -30
  174. package/dist/message-stream/normalizer.d.ts +0 -21
  175. package/dist/message-stream/parser.d.ts +0 -89
  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/response-parser.d.ts +0 -24
  179. package/dist/message-stream/sanitize.d.ts +0 -10
  180. package/dist/message-stream/stream.d.ts +0 -54
  181. package/dist/message-stream/types.d.ts +0 -97
  182. package/dist/message-stream/validator.d.ts +0 -23
  183. package/dist/prompts/chat-mode/protocol.d.ts +0 -2
  184. package/dist/prompts/chat-mode/system.d.ts +0 -2
  185. package/dist/prompts/chat-mode/system.md.d.ts +0 -2
  186. package/dist/prompts/chat-mode/user.d.ts +0 -2
  187. package/dist/prompts/chat-mode/user.md.d.ts +0 -2
  188. package/dist/prompts/code-examples.d.ts +0 -2
  189. package/dist/prompts/common.d.ts +0 -7
  190. package/dist/prompts/dual-modes.d.ts +0 -2
  191. package/dist/prompts/execution-history.d.ts +0 -6
  192. package/dist/prompts/execution-state.d.ts +0 -3
  193. package/dist/prompts/protocol-basics.d.ts +0 -5
  194. package/dist/prompts/protocol.d.ts +0 -31
  195. package/dist/prompts/worker-mode/protocol.d.ts +0 -2
  196. package/dist/prompts/worker-mode/system.d.ts +0 -2
  197. package/dist/prompts/worker-mode/system.md.d.ts +0 -2
  198. package/dist/prompts/worker-mode/user.d.ts +0 -2
  199. package/dist/prompts/worker-mode/user.md.d.ts +0 -2
  200. package/dist/quickjs-variant-BYhMBpwU.js +0 -45
  201. package/dist/quickjs-variant-CsIwTVFC.cjs +0 -56
  202. package/dist/rolldown-runtime-EAsCxrDo.js +0 -14
  203. package/dist/runtime/fixtures/qwen-protocol-failures.d.ts +0 -29
  204. package/dist/runtime/interpret-result.d.ts +0 -22
  205. package/dist/snapshots.d.ts +0 -249
  206. package/dist/stack-traces-BIE_5Xwf.js +0 -21
  207. package/dist/stack-traces-ntw_qhoy.cjs +0 -26
  208. package/dist/truncator-CLkouTCO.cjs +0 -276
  209. package/dist/truncator-DZqEqnpD.js +0 -253
  210. package/dist/truncator.d.ts +0 -118
  211. package/dist/utils-3ESwP3yg.cjs +0 -1075
  212. package/dist/utils-UBeAFeEI.js +0 -950
  213. /package/dist/{citations.d.ts → chat/citations.d.ts} +0 -0
  214. /package/dist/{citations.test.d.ts → chat/citations.test.d.ts} +0 -0
  215. /package/dist/{component.default.test.d.ts → chat/component.default.test.d.ts} +0 -0
  216. /package/dist/{compiler/plugins/track-tool-calls.test.d.ts → chat/component.test.d.ts} +0 -0
  217. /package/dist/{example.test.d.ts → chat/response.test.d.ts} +0 -0
  218. /package/dist/{exit-parser.test.d.ts → compiler/plugins/dynamic-code.test.d.ts} +0 -0
  219. /package/dist/{handlers.test.d.ts → compiler/plugins/tool-resolution.test.d.ts} +0 -0
  220. /package/dist/{hoist.test.d.ts → errors/catalog.test.d.ts} +0 -0
  221. /package/dist/{message-stream/instructions.test.d.ts → exit.test.d.ts} +0 -0
  222. /package/dist/{message-stream/normalizer.test.d.ts → inspection.test.d.ts} +0 -0
  223. /package/dist/{message-stream/parser.test.d.ts → prompts/native.test.d.ts} +0 -0
  224. /package/dist/{message-stream/response-parser.test.d.ts → result.test.d.ts} +0 -0
  225. /package/dist/{message-stream/stream.test.d.ts → runtime/chat-completion.test.d.ts} +0 -0
  226. /package/dist/{message-stream/validator.test.d.ts → runtime/chat-delivery.test.d.ts} +0 -0
  227. /package/dist/{prompts/adherence.test.d.ts → runtime/chat-last-speaker.test.d.ts} +0 -0
  228. /package/dist/{prompts/catalogue-examples.test.d.ts → runtime/compatibility-regressions.test.d.ts} +0 -0
  229. /package/dist/{prompts/code-examples.test.d.ts → runtime/context-registration.test.d.ts} +0 -0
  230. /package/dist/{prompts/common.test.d.ts → runtime/empty-completion.test.d.ts} +0 -0
  231. /package/dist/{prompts/concrete-patterns.test.d.ts → runtime/error-recovery.test.d.ts} +0 -0
  232. /package/dist/{prompts/long-search.test.d.ts → runtime/errors.test.d.ts} +0 -0
  233. /package/dist/{prompts/protocol-simple.test.d.ts → runtime/execution-activity.test.d.ts} +0 -0
  234. /package/dist/{prompts/protocol.test.d.ts → runtime/execution-diagnostics.test.d.ts} +0 -0
  235. /package/dist/{prompts/sections.test.d.ts → runtime/execution-report.test.d.ts} +0 -0
  236. /package/dist/runtime/{interpret-result.test.d.ts → execution-safety.test.d.ts} +0 -0
  237. /package/dist/{transcript.test.d.ts → runtime/exit-control-flow.test.d.ts} +0 -0
  238. /package/dist/{truncator.test.d.ts → runtime/fixtures/long-search.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,639 +1,153 @@
1
- # LLMz
1
+ # LLMZ
2
2
 
3
- **Stop chaining tools. Start generating code.**
3
+ LLMZ runs agents that use JavaScript to call tools, work with data, and return typed outcomes. The model receives one native `run_javascript` tool. Programs run in a sandbox; the host supplies the business tools they can call.
4
4
 
5
- LLMz is a TypeScript AI agent framework that replaces traditional JSON tool calling with executable code generation. Instead of orchestrating tools through multiple LLM roundtrips, agents write and execute TypeScript directly—enabling complex logic, loops, and multi-tool coordination in a single pass.
5
+ Use `Session` for conversation history and retained values, `Chat` for text and component delivery, and `Exit` for structured completion.
6
6
 
7
- Powers millions of production agents at [Botpress](https://botpress.com).
7
+ [API guide](./DOCS.md) · [Examples](./examples) · [Migration](./DOCS.md#migrating-from-the-previous-api)
8
8
 
9
- | | |
10
- | --- | ----------------------------------------------------------------------------------------- |
11
- | 📚 | [**Examples →**](https://github.com/botpress/botpress/tree/master/packages/llmz/examples) |
9
+ ## Installation
12
10
 
13
- ---
14
-
15
- ## The Problem with Tool Calling
16
-
17
- Traditional agentic frameworks (LangChain, CrewAI, MCP servers) rely on JSON tool calling:
18
-
19
- ```json
20
- {
21
- "tool": "getTicketPrice",
22
- "parameters": { "from": "quebec", "to": "new york" }
23
- }
24
- ```
25
-
26
- This breaks down quickly:
27
-
28
- - **Verbose schemas**: LLMs struggle with complex JSON structures
29
- - **No logic**: Can't express conditionals, loops, or error handling
30
- - **Multiple roundtrips**: Each tool call requires another LLM inference ($$$)
31
- - **Fragile composition**: Chaining tools is error-prone and expensive
32
-
33
- You end up with brittle agents that cost 10-100x more than they should.
34
-
35
- ---
36
-
37
- ## The LLMz Solution
38
-
39
- LLMz generates and executes **real TypeScript code** in a secure sandbox:
40
-
41
- ```typescript
42
- const price = await getTicketPrice({ from: 'quebec', to: 'new york' })
43
-
44
- if (price > 500) {
45
- throw new Error('Price too high')
46
- }
47
-
48
- const ticketId = await buyTicket({ from: 'quebec', to: 'new york' })
49
- ```
50
-
51
- **Why this works:**
52
-
53
- - LLMs have seen billions of lines of TypeScript—they're exceptionally good at it
54
- - Complex logic (loops, conditionals, error handling) happens in one inference
55
- - Multiple tool calls execute synchronously without LLM roundtrips
56
- - Full type safety via Zui schemas and TypeScript inference
57
-
58
- **Real-world impact**: Anthropic reduced agent costs by 98.7% using code execution patterns ([source](https://www.anthropic.com/engineering/code-execution-with-mcp)).
59
-
60
- ---
61
-
62
- ## The ■ Protocol
63
-
64
- Every model response is a sequence of streaming-native `■` blocks:
65
-
66
- ```
67
- ■start
68
- ■send=message
69
- Let me check the next launch dates for the Moon...
70
- ■run
71
- const dates = await checkAvailability({ destination: 'moon' })
72
- const reservation = await bookTrip({ destination: 'moon', date: dates[0], travelerName: 'Ada' })
73
- const payment = await processPayment({ reservationId: reservation.reservationId })
74
- return { ...payment, date: dates[0] }
75
- ■end
76
- ```
77
-
78
- - **`■send=<component> {props?}`** — sends a message to the user, streamed provisionally, then delivered after successful validation
79
- - **`■run`** — executes the JavaScript body in the sandbox; the returned value is fed back to the model
80
- - **`■next=<exit> {props?}`** — ends the turn through a typed exit (the built-in `listen` hands the turn back to the user)
81
-
82
- Every generated response must contain a standalone `■start` and end with `■end`. Text before the start marker is retained for debugging and discarded before parsing any blocks. There is no unwrapped response mode. Only explicit `■send` blocks can produce messages. Markdown (`■send=md`) remains supported.
83
-
84
- Message bodies stream as provisional deltas. Completed message handlers and code execution wait for the entire valid response and successful generation. A missing start marker, unmarked prose inside the envelope, multiple run blocks, and messages after code reject the response through the normal malformed-response/error path. A failed or restarted attempt cannot execute code or commit a message. Any previews from it are retracted with a reset delta.
85
-
86
- The first `■end` is a reserved terminator anywhere after `■start`, including inline and inside a JavaScript string or comment. Everything after it is discarded with a diagnostic; it never reaches message handlers or code execution. This intentionally accepts concatenated output such as `■end■start`. The prefix must still form valid blocks and valid JavaScript before any code runs. A terminator inside a string can therefore invalidate the response; do not use the raw sequence as content. In JavaScript, construct literal text with a Unicode escape such as `"\u25a0end"` instead. This is a protocol delimiter, not a JavaScript-aware scanner.
87
-
88
- Cognitive receives `stopSequences: ['\n■end']` to stop generation at the end boundary. Since providers consume the stop string, normal `stop` metadata closes the response even when the literal end marker is absent. Cognitive does not distinguish a matched stop string from ordinary end-of-generation; the response must still have a start marker and valid blocks. Missing metadata, truncation, filtering, and transport failure never supply this closure.
89
-
90
- Raw output and diagnostics remain available in `iteration.llm.output` and `iteration.llm.diagnostics`, including on failed streams. A valid framed exit alone permits intentional silence. Tools completed in earlier successful iterations remain completed during later recovery.
91
-
92
- Prompt examples use standalone triple quotes (`"""`) to show their boundaries, with BAD/CORRECT comparisons and a menu of response shapes. These quotes are documentation, not protocol. If copied, standalone example delimiter lines are stripped before customer callbacks and recorded as `example-delimiter` diagnostics. Inline quotes, JSON props, and interior Markdown/code content remain literal. A standalone triple-quote line immediately before a protocol boundary is reserved for this purpose; to display it literally, include it inline or inside a fenced code sample.
93
-
94
- The prompts use ordinary headings and put the response format after task context and the current execution budget. Historical replies are kept as recorded, without synthetic protocol headers. The low-level block parser remains useful for parsing individual blocks; execution uses the mandatory response envelope.
95
-
96
- This is a breaking protocol change: custom model clients and cached wire responses must include the start boundary and a successful response termination. Completed handlers now run after successful generation; only deltas stream during generation. `■run` followed by `■send` is invalid. Return a tool result, then answer in a new iteration. The removed `strict` and `recoveryComponent` options are not restored.
97
-
98
- To measure first-response adherence independently of runtime recovery, configure `CLOUD_PAT`, `CLOUD_BOT_ID`, and optionally `CLOUD_API_ENDPOINT`, then run:
99
-
100
- ```bash
101
- LLMZ_EVAL_MODELS=cerebras:qwen-3.8-27b LLMZ_EVAL_REPEATS=1 pnpm test:e2e e2e/protocol-matrix.test.ts
102
- ```
103
-
104
- The matrix contains 144 synthetic tasks across 12 languages, each in streaming and nonstreaming mode: greetings, intake, long context, tools, progress messages, tool results, silent actions, typed exits, buttons, JSON text, Markdown, and error recovery. It disables test retries and cache and rejects fallback credit. Optional `LLMZ_EVAL_RECORDS=/absolute/path/results.jsonl` records raw outputs, diagnostics, task checks, and actual model metadata. Failures remain visible: passing runtime rejection tests does not establish perfect model adherence. Protocol/control-flow assertions are separate from exact task wording checks, which are retained in the evaluation records.
105
-
106
- ---
107
-
108
- ## Long search results and citations
109
-
110
- The RAG benchmark uses the same citation contract as VDK: a search tool registers source metadata, returns passages labelled with `【id】` through `ThinkSignal`, and the completed message handler extracts inline tags into citation metadata with text offsets. Its documents are entirely synthetic.
111
-
112
- ```bash
113
- LLMZ_EVAL_MODELS=groq:qwen3.8-27b LLMZ_EVAL_REPEATS=1 pnpm test:e2e e2e/long-search-citations.test.ts
114
- ```
115
-
116
- The 48 cases pair compact controls with long corpora in both streaming modes. They cover exact scope matching, superseded/future policies, joins across distant documents, and quota arithmetic, with answers near the beginning, middle, or end. Results span roughly 12,000–39,000 tokens and four response languages. Tests require correct facts, every required supporting source, no unrelated citations, intact evidence in the actual model request, no extra search/recovery hops, and the requested model without cache or fallback credit. Near-match sources may additionally support scope/date disambiguation (for example, explaining why an archived account does not apply); they cannot replace required evidence. These checks validate retrieval and source coverage, not every possible natural-language claim.
117
-
118
- Latest tool-result strings are preserved until the request context budget is applied; they are no longer silently clipped at 4,096 characters. Inputs exceeding the model/context budget still undergo normal truncation. Separate deterministic tests cover citation offsets, grouped/repeated tags, structured component props, chunk boundaries, discarded preambles, stream restarts, failed delivery, and unknown source IDs.
119
-
120
- ---
121
-
122
- ## Quick Start
123
-
124
- **Requirements:** Node.js 20+
125
-
126
- ```bash
127
- npm install @botpress/client llmz
11
+ ```sh
12
+ pnpm add llmz @botpress/cognitive @bpinternal/zui @bpinternal/thicktoken
128
13
  ```
129
14
 
130
- ### Platform Support
15
+ The following examples assume `BOTPRESS_BOT_ID` and `BOTPRESS_TOKEN` are configured for Cognitive. Examples are type-checked with `pnpm check:docs`.
131
16
 
132
- | Platform | Support |
133
- | ------------------ | ------- |
134
- | Node.js 20+ | ✅ Full |
135
- | Browser | ✅ Full |
136
- | AWS Lambda | ✅ Full |
137
- | Cloudflare Workers | ✅ Full |
138
- | Bun | ✅ Full |
139
- | Deno | ✅ Full |
17
+ ## Start a conversation
140
18
 
141
- #### Sandbox Execution
19
+ ```ts
20
+ import { Cognitive } from '@botpress/cognitive'
21
+ import { Chat, Session, execute } from 'llmz'
142
22
 
143
- LLMz uses **QuickJS** (a lightweight JavaScript engine compiled to WebAssembly) to execute generated code in a secure, isolated sandbox. This provides:
144
-
145
- - **Complete isolation**: No access to filesystem, network, or host environment
146
- - **Memory limits**: Configurable heap size to prevent resource exhaustion
147
- - **Execution timeouts**: Automatic termination of runaway code
148
- - **Abort signals**: Support for programmatic execution cancellation
149
- - **Universal compatibility**: Works everywhere WebAssembly is supported
150
-
151
- The QuickJS sandbox is bundled as a singlefile variant with WASM inlined as base64, so it works out-of-the-box with any bundler (esbuild, webpack, vite, rollup) without configuration.
152
-
153
- ### Worker Mode: Autonomous Execution
154
-
155
- ```typescript
156
- import { Client } from '@botpress/client'
157
- import { execute } from 'llmz'
158
-
159
- const client = new Client({ botId: '...', token: '...' })
160
-
161
- const result = await execute({
162
- instructions: 'Calculate sum of integers 14-1078 divisible by 3, 9, or 5',
163
- client,
23
+ const client = new Cognitive({
24
+ botId: process.env.BOTPRESS_BOT_ID!,
25
+ token: process.env.BOTPRESS_TOKEN!,
164
26
  })
165
-
166
- console.log(result.output) // 271575
167
- ```
168
-
169
- **Generated response:**
170
-
171
- ```
172
- ■run
173
- let sum = 0
174
- for (let i = 14; i <= 1078; i++) {
175
- if (i % 3 === 0 || i % 9 === 0 || i % 5 === 0) {
176
- sum += i
177
- }
178
- }
179
- return sum
180
- ```
181
-
182
- ### Chat Mode: Interactive Agents
183
-
184
- ```typescript
185
- import { execute, Chat, DefaultComponents, ListenExit } from 'llmz'
186
-
187
- const transcript = []
188
-
27
+ const session = new Session()
189
28
  const chat = new Chat({
190
- components: [DefaultComponents.Text, DefaultComponents.Button],
191
- transcript: () => transcript,
192
-
193
- // Complete messages, delivered as soon as they are parsed
194
- handler: async (component) => {
195
- render(component)
196
- },
197
-
198
- // Optional: message body chunks, streamed while the LLM is still generating
199
- onMessageDelta: (delta) => {
200
- appendToBubble(delta.id, delta.delta)
29
+ response: {
30
+ preset: 'markdown',
31
+ handler: (text) => {
32
+ console.log(text)
33
+ },
201
34
  },
202
35
  })
203
36
 
204
- while (true) {
205
- const result = await execute({ client, chat, tools: [searchFlights, bookTicket] })
37
+ session.append({ role: 'user', content: 'Help me plan a weekend in Montreal.' })
38
+ const result = await execute({ client, session, chat, instructions: 'Be concise and helpful.' })
206
39
 
207
- if (result.is(ListenExit)) {
208
- // Agent handed the turn back — wait for user input
209
- transcript.push({ role: 'user', content: await getUserInput() })
210
- } else {
211
- break // Agent completed (custom exit) or errored
212
- }
40
+ if (result.isError()) {
41
+ console.error(result.error)
213
42
  }
214
43
  ```
215
44
 
216
- **Generated response:**
45
+ Append the next message and call `execute` again with the same session. Inputs appended during execution wait for the next turn. Await one execution before starting another on that session.
217
46
 
218
- ```
219
- ■send=message
220
- Found 12 flights. The cheapest is **$249**. Want me to book it?
221
- ■send=button {"label": "Book flight", "action": "postback", "value": "book"}
222
- ■send=button {"label": "Cancel", "action": "postback", "value": "cancel"}
223
- ■next=listen
224
- ```
47
+ ## Return a typed result
225
48
 
226
- ---
49
+ Workers complete through a named exit. Tool input and exit output use Zui schemas.
227
50
 
228
- ## Core Concepts
229
-
230
- ### Execution Modes
231
-
232
- **Worker Mode**: Autonomous agents that execute to completion
233
-
234
- ```typescript
235
- const result = await execute({
236
- instructions: 'Analyze Q4 sales data and generate report',
237
- client,
238
- tools: [fetchSales, calculateMetrics, generatePDF],
239
- })
240
- ```
241
-
242
- **Chat Mode**: Interactive conversations with user input
243
-
244
- ```typescript
245
- const result = await execute({
246
- client,
247
- tools,
248
- chat, // a Chat instance: components + transcript + message handler
249
- })
250
- ```
251
-
252
- ### Tools: Type-Safe Functions
253
-
254
- ```typescript
255
- import { Tool } from 'llmz'
51
+ ```ts
52
+ import { Cognitive } from '@botpress/cognitive'
256
53
  import { z } from '@bpinternal/zui'
54
+ import { Exit, Tool, execute } from 'llmz'
257
55
 
258
- const searchFlights = new Tool({
259
- name: 'searchFlights',
260
- description: 'Search for available flights',
261
- input: z.object({
262
- from: z.string(),
263
- to: z.string(),
264
- date: z.string(),
265
- }),
266
- output: z.array(
267
- z.object({
268
- id: z.string(),
269
- price: z.number(),
270
- departure: z.string(),
271
- })
272
- ),
273
- handler: async ({ from, to, date }) => {
274
- // Your implementation
275
- return flights
276
- },
56
+ const client = new Cognitive({
57
+ botId: process.env.BOTPRESS_BOT_ID!,
58
+ token: process.env.BOTPRESS_TOKEN!,
277
59
  })
278
- ```
279
-
280
- Tools are exposed to agents with full TypeScript signatures. Agents call them like regular async functions — and chain them freely inside a single `■run` block.
281
-
282
- Tool handlers can also be **async generators** that push UI components to the chat mid-execution (progress bars, previews) before returning their result — see [example 21](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/21_chat_tool_components).
283
-
284
- ### Objects: Namespaced State
285
-
286
- Group related tools and variables:
287
-
288
- ```typescript
289
- import { ObjectInstance } from 'llmz'
290
- import { z } from '@bpinternal/zui'
291
-
292
- const database = new ObjectInstance({
293
- name: 'db',
294
- description: 'Database operations',
295
- tools: [queryUsers, updateRecord, deleteRecord],
296
- properties: [
297
- {
298
- name: 'connectionString',
299
- value: process.env.DB_URL,
300
- writable: false,
301
- },
302
- {
303
- name: 'lastQueryTime',
304
- value: null,
305
- type: z.string().nullable(),
306
- writable: true,
307
- },
308
- ],
60
+ const getPrice = new Tool({
61
+ name: 'getPrice',
62
+ description: 'Look up the unit price of an item.',
63
+ input: z.object({ sku: z.string() }),
64
+ output: z.number(),
65
+ handler: async ({ sku }) => (sku === 'coffee' ? 12 : 0),
309
66
  })
310
- ```
311
-
312
- Agents access via namespaces:
313
-
314
- ```typescript
315
- const users = await db.queryUsers({ active: true })
316
- db.lastQueryTime = new Date().toISOString()
317
- ```
318
-
319
- ### Exits: Structured Termination
320
-
321
- Define how agents can complete:
322
-
323
- ```typescript
324
- import { Exit } from 'llmz'
325
- import { z } from '@bpinternal/zui'
326
-
327
- const TicketBooked = new Exit({
328
- name: 'ticket_booked',
329
- description: 'Successfully booked a ticket',
330
- schema: z.object({
331
- ticketId: z.string(),
332
- price: z.number(),
333
- confirmation: z.string(),
334
- }),
67
+ const done = new Exit({
68
+ name: 'done',
69
+ description: 'Return the calculated total.',
70
+ schema: z.object({ total: z.number() }),
335
71
  })
336
72
 
337
73
  const result = await execute({
338
74
  client,
339
- tools,
340
- exits: [TicketBooked],
75
+ instructions: 'Calculate the price of three units of coffee and finish with done.',
76
+ tools: [getPrice],
77
+ exits: [done],
341
78
  })
342
79
 
343
- if (result.is(TicketBooked)) {
344
- console.log('Booked:', result.output.ticketId) // Fully typed
80
+ if (result.is(done)) {
81
+ console.log(result.output.total)
82
+ } else if (result.isError()) {
83
+ console.error(result.error)
345
84
  }
346
85
  ```
347
86
 
348
- Agents invoke exits with a `■next` block:
87
+ The model can compose tool calls in a program. It uses `return inspect(value)` to examine evidence in another iteration, and `return exit('done', payload)` to finish. [Execution and memory](./DOCS.md#execution-and-memory) explains their lifetimes.
349
88
 
350
- ```
351
- ■next=ticket_booked {"ticketId": "TKT-12345", "price": 299, "confirmation": "ABC123"}
352
- ```
89
+ ## Save a conversation
353
90
 
354
- ---
91
+ Persist the session after execution settles. The execution result contains the outcome and diagnostics for one run.
355
92
 
356
- ## Streaming
93
+ ```ts
94
+ import { Session } from 'llmz'
357
95
 
358
- With a streaming client (`CognitiveBeta` / Cognitive v2), everything an execution produces surfaces in real time:
96
+ const session = new Session({ variables: { accountId: 'customer-42' } })
97
+ session.append({ role: 'user', content: 'Check my account.' })
359
98
 
360
- ```typescript
361
- const chat = new Chat({
362
- components: [DefaultComponents.Text],
363
- transcript: () => transcript,
364
- handler: async (component, metadata) => finalizeBubble(component, metadata),
365
- // Fires per token-chunk while the LLM is still generating
366
- onMessageDelta: (delta) => {
367
- if (delta.restart) {
368
- // Remove this iteration's provisional previews.
369
- return clearIterationMessages(delta.iterationId)
370
- }
371
- return updateBubble(delta.iterationId, delta.id, delta.content)
372
- },
373
- })
99
+ const saved = JSON.stringify(session.toJSON())
100
+ const restored = Session.fromJSON(JSON.parse(saved))
374
101
 
375
- const result = await execute({
376
- client, // CognitiveBeta
377
- chat,
378
- tools,
379
- options: { midStreamFallback: true },
380
- onTrace: ({ trace }) => {
381
- if (trace.type === 'llm_call_started') showSpinner()
382
- if (trace.type === 'code_generation_started') showStatus('writing code…')
383
- if (trace.type === 'llm_call_success') showCode(trace.code)
384
- if (trace.type === 'tool_call') showToolCall(trace)
385
- },
386
- })
102
+ console.log(restored.pendingMessages)
103
+ console.log(restored.memory.variables.accountId)
387
104
  ```
388
105
 
389
- - **Message deltas** stream to your UI token-by-token (`handler` remains the authoritative delivery)
390
- - **Live traces** cover the full turn lifecycle: `llm_call_started` → message deltas → `code_generation_started` → `llm_call_success` (with the code) → `tool_call`s → exit
391
- - **Fallback**: a `restart: true` delta invalidates the current iteration's messages before replacement output arrives. Replacement messages have fresh IDs under the same `iterationId`. Code executes only after the replacement stream succeeds; abandoned code never runs.
392
- - **Execution**: code runs only after a complete, valid envelope and successful stream completion in every mode. The VM still pre-warms when a run block opens.
393
-
394
- Terminal failures return an `ErrorExecutionResult` and retract any provisional previews with a reset delta; no replacement is required for a reset. Completed handlers from abandoned attempts are never called. Nonstreaming fallback exposes only the surviving response.
395
-
396
- Explicit Cognitive errors, unknown-provider error metadata, missing streaming metadata, token-limit truncation, and content filtering cannot turn partial output into executable code. A complete code block inside an unfinished response is still provisional.
397
-
398
- Send messages before code. A returning run requests another iteration and must be followed directly by `■end`. Side-effect-only code may finish with `■next` before `■end`.
399
-
400
- Forward these events over a websocket or SSE stream and your frontend renders the agent live — see [example 22](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/22_chat_streaming).
401
-
402
- ### Token Usage & Timings
403
-
404
- Every iteration reports what it consumed:
405
-
406
- ```typescript
407
- const { input, output, total, limit, context } = result.iteration.tokens
408
- // context measures the prompt size by part (pre-truncation):
409
- // { framework, instructions, tools, transcript, protocol, iterations, total }
410
- console.log(`context used: ${Math.round((context.total / limit) * 100)}%`)
411
-
412
- const { time_to_first_token, time_to_last_token } = result.iteration.llm
413
-
414
- // Aggregated across all iterations:
415
- console.log(result.tokens) // { input, output, total }
416
- ```
417
-
418
- ### Execution Options
419
-
420
- ```typescript
421
- const result = await execute({
422
- client,
423
- model: ['cerebras:gpt-oss-120b', 'anthropic:claude-haiku-4-5'], // fallback chain
424
- reasoningEffort: 'low', // 'low' | 'medium' | 'high' | 'dynamic' | 'none'
425
- options: {
426
- loop: 5, // max iterations
427
- timeout: 60_000, // VM execution timeout (ms)
428
- maxTokens: 32_000, // context window cap: min(maxTokens, model max)
429
- maxTimeToFirstToken: 5_000, // fall back to the next model if the first token is late (ms)
430
- },
431
- })
432
- ```
433
-
434
- ---
435
-
436
- ## Advanced Features
437
-
438
- ### Thinking: Forced Reflection
439
-
440
- Tools can force the agent to look at data before acting on it:
441
-
442
- ```typescript
443
- import { ThinkSignal } from 'llmz'
444
-
445
- const complexAnalysis = new Tool({
446
- name: 'analyze',
447
- handler: async (data) => {
448
- const result = performComplexCalculation(data)
449
- // Force agent to reflect on results before proceeding
450
- throw new ThinkSignal('Analysis complete. Review data before next step.')
451
- },
452
- })
453
- ```
454
-
455
- Agents self-initiate reflection by returning values from their code — the returned value is shown to them and they respond again:
456
-
457
- ```
458
- ■run
459
- const data = await fetchLargeDataset()
460
- return data.summary
461
- ```
106
+ A failed execution retains its active turn. Calling `execute` again continues that turn; newly queued input remains separate. Completed tool effects are not rolled back. [Persistence and recovery](./DOCS.md#persistence-and-recovery) documents this contract.
462
107
 
463
- ### Snapshots: Pause and Resume
108
+ ## Stream text
464
109
 
465
- Save execution state for long-running workflows:
110
+ `onDelta` receives provisional text. `handler` receives the complete accepted response. A restart retracts the preview for that iteration.
466
111
 
467
- ```typescript
468
- import { SnapshotSignal } from 'llmz'
112
+ ```ts
113
+ import { Chat } from 'llmz'
469
114
 
470
- const approvalRequired = new Tool({
471
- name: 'submitForApproval',
472
- handler: async (request) => {
473
- await saveToDatabase(request)
474
- // Halt execution until manual approval
475
- throw new SnapshotSignal('Awaiting manager approval')
476
- },
477
- })
478
-
479
- // Later, resume from snapshot
480
- const result = await execute({
481
- client,
482
- snapshot: savedSnapshot,
483
- })
484
- ```
485
-
486
- ### Hooks: Custom Logic Injection
487
-
488
- ```typescript
489
- const result = await execute({
490
- client,
491
- tools,
492
-
493
- // Non-blocking: observe everything (and abort when needed)
494
- onTrace: ({ trace, controller }) => {
495
- logger.info(trace)
496
- if (trace.type === 'tool_call' && trace.tool_name === 'forbidden') {
497
- controller.abort('Forbidden tool call')
498
- }
499
- },
500
-
501
- // Validate before allowing an exit — throw to retry, abort to stop
502
- onExit: (result, controller) => {
503
- if (result.exit.name === 'transfer_money' && result.result.amount > 10_000) {
504
- throw new Error('Amount exceeds limit')
505
- }
506
- },
507
-
508
- // Inspect/modify generated code before execution
509
- onBeforeExecution: (iteration) => {
510
- if (iteration.code?.includes('dangerousOperation')) {
511
- return { code: '// blocked' }
512
- }
115
+ const previews = new Map<string, string>()
116
+ const chat = new Chat({
117
+ response: {
118
+ preset: 'text',
119
+ onDelta: (event) => {
120
+ if (event.restart) {
121
+ previews.delete(event.iterationId)
122
+ } else {
123
+ previews.set(event.iterationId, event.content)
124
+ }
125
+ },
126
+ handler: (text, metadata) => {
127
+ previews.delete(metadata.iterationId)
128
+ console.log(metadata.id, text)
129
+ },
513
130
  },
514
-
515
- // Also available: onIterationStart, onIterationEnd, onBeforeTool, onAfterTool
516
131
  })
517
132
  ```
518
133
 
519
- ---
520
-
521
- ## Coming from MCP?
522
-
523
- LLMz is **not** a replacement for MCP—it's complementary.
524
-
525
- **MCP** (Model Context Protocol): Standardizes how AI applications connect to data sources and tools across processes/machines.
526
-
527
- **LLMz**: Replaces the execution pattern _after_ tools are exposed. Instead of making multiple LLM calls to orchestrate MCP tools via JSON, LLMz generates TypeScript code that calls those same tools in a single inference—reducing costs by up to 98%.
528
-
529
- ---
134
+ Streaming requires a client with `generateTextStream`. See [streaming semantics](./DOCS.md#streaming-and-delivery) before enabling model fallback.
530
135
 
531
- ## Production Ready
136
+ ## Examples and development
532
137
 
533
- LLMz has been running in production for over a year:
138
+ - [Basic chat](./examples/01_chat_basic/index.ts)
139
+ - [Typed chat exits](./examples/02_chat_exits/index.ts)
140
+ - [Rich components](./examples/10_chat_components/index.ts)
141
+ - [Worker tool chaining](./examples/16_worker_tool_chaining/index.ts)
142
+ - [Streaming chat](./examples/22_chat_streaming/index.ts)
534
143
 
535
- - **Millions** of active users across enterprise and consumer applications
536
- - **Hundreds of thousands** of deployed agents handling real-world workloads
537
- - **Secure sandbox**: Uses QuickJS WASM for isolated code execution
538
- - **Type-safe**: Full TypeScript inference and Zui validation
539
- - **Observable**: Comprehensive tracing, token accounting and error handling
540
-
541
- ---
542
-
543
- ## Architecture
544
-
545
- **Execution Pipeline:**
546
-
547
- 1. **Prompt Generation**: Injects tools, schemas, and context into dual-mode prompts
548
- 2. **Streaming Generation**: The LLM streams ■ blocks — messages dispatch to the chat as they are parsed
549
- 3. **Compilation**: Babel AST transformation with instrumentation plugins (line tracking, tool call tracking, variable extraction)
550
- 4. **Execution**: Runs in QuickJS WASM sandbox with full isolation — after successful generation and protocol validation
551
- 5. **Result Processing**: Type-safe exit handling, thinking loops and error recovery
552
-
553
- **Security:**
554
-
555
- - QuickJS WASM sandbox with complete isolation (no filesystem/network access)
556
- - Stack trace sanitization (removes internal framework details)
557
- - Configurable memory limits and execution timeouts
558
- - Tool-level permissions and rate limiting
559
- - Automatic token limit handling
560
-
561
- ---
562
-
563
- ## Comparison
564
-
565
- | Feature | LangChain / CrewAI | MCP Servers | LLMz |
566
- | ------------------------ | ---------------------- | ---------------------- | ------------------------- |
567
- | Tool calling | JSON | JSON | TypeScript code |
568
- | Multi-tool orchestration | Multiple LLM calls | Multiple LLM calls | Single LLM call |
569
- | Complex logic | Limited | Limited | Full language support |
570
- | Type safety | Partial | Schema-based | Full TypeScript + Zui |
571
- | Streaming | Text only | Text only | Messages, code, tools |
572
- | Execution environment | Python/JS runtime | Cross-process | QuickJS WASM sandbox |
573
- | Cost (complex workflows) | High (many roundtrips) | High (many roundtrips) | Low (one-shot generation) |
574
- | Production scale | Varies | Emerging | Battle-tested (1M+ users) |
575
-
576
- ---
577
-
578
- ## Examples
579
-
580
- Check out the [examples folder](https://github.com/botpress/botpress/tree/master/packages/llmz/examples) for complete working examples:
581
-
582
- | Title | Mode | Description |
583
- | --------------------------------------------------------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------- |
584
- | [Basic Chat](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/01_chat_basic) | Chat | Simple interactive chat with button-based navigation |
585
- | [Chat with Exits](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/02_chat_exits) | Chat | Custom exit conditions with type-safe validation |
586
- | [Conditional Tools](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/03_chat_conditional_tool) | Chat | Dynamic tool availability based on context |
587
- | [Small Models](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/04_chat_small_models) | Chat | Optimized prompts for smaller language models |
588
- | [Web Search](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/05_chat_web_search) | Chat | Integrate web search and content browsing |
589
- | [Tool Confirmation](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/06_chat_confirm_tool) | Chat | User confirmation before executing tools |
590
- | [Guardrails](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/07_chat_guardrails) | Chat | Safety constraints and content filtering |
591
- | [Multi-Agent](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/08_chat_multi_agent) | Chat | Coordinating multiple agents in one system |
592
- | [Variables](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/09_chat_variables) | Chat | Stateful properties that persist across iterations |
593
- | [Components](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/10_chat_components) | Chat | Rich UI components for interactive experiences |
594
- | [Minimal Worker](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/11_worker_minimal) | Worker | One-shot computational task execution |
595
- | [File System](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/12_worker_fs) | Worker | Automated file operations with conditional logic |
596
- | [Sandbox](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/13_worker_sandbox) | Worker | Secure isolated code execution environment |
597
- | [Snapshots](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/14_worker_snapshot) | Worker | Pause and resume long-running workflows |
598
- | [Stack Traces](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/15_worker_stacktraces) | Worker | Error handling and debugging patterns |
599
- | [Tool Chaining](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/16_worker_tool_chaining) | Worker | Sequential multi-tool orchestration |
600
- | [Error Recovery](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/17_worker_error_recovery) | Worker | Graceful failure handling and retries |
601
- | [Security](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/18_worker_security) | Worker | Code inspection and security validation |
602
- | [Wrap Tools](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/19_worker_wrap_tool) | Worker | Creating higher-order tool abstractions |
603
- | [RAG](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/20_chat_rag) | Chat | Retrieval-augmented generation with knowledge bases |
604
- | [Tool Components](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/21_chat_tool_components) | Chat | Tool handlers pushing UI components mid-execution |
605
- | [Streaming](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/22_chat_streaming) | Chat | Guided simulation: streamed messages, live code + tool calls, typed exits, per-turn stats |
606
-
607
- ---
608
-
609
- ## Contributing
610
-
611
- ```bash
612
- git clone https://github.com/botpress/botpress
613
- cd packages/llmz
614
-
615
- pnpm install
144
+ ```sh
616
145
  pnpm test
617
- pnpm build
146
+ pnpm check:type
147
+ pnpm check:e2e:type
148
+ pnpm check:docs
149
+ pnpm check:lint
150
+ pnpm check:format
618
151
  ```
619
152
 
620
- **Commands:**
621
-
622
- - `pnpm test`: Run test suite (Vitest with LLM retries)
623
- - `pnpm test:watch`: Watch mode for development
624
- - `pnpm build`: Compile TypeScript and bundle (ESM + CJS)
625
- - `pnpm generate`: Regenerate prompt templates from markdown
626
-
627
- ---
628
-
629
- ## License
630
-
631
- MIT
632
-
633
- ---
634
-
635
- ## Learn More
636
-
637
- - [Anthropic: Code Execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp)
638
- - [How Code Execution Reduces Agent Costs by 98%](https://medium.com/@meshuggah22/weve-been-using-mcp-wrong-how-anthropic-reduced-ai-agent-costs-by-98-7-7c102fc22589)
639
- - [Botpress Documentation](https://botpress.com/docs)
153
+ Unit tests use scripted clients. Model evaluations run separately through `pnpm test:e2e` and require the configured provider credentials.