llmz 0.0.28 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,85 @@
1
- # 🚀 LLMz: Next-Gen TypeScript AI Agent Framework
1
+ # LLMz
2
2
 
3
- **Build AI agents that think, code, and execute like humans—powered by TypeScript and battle-tested at massive scale.**
3
+ **Stop chaining tools. Start generating code.**
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.
6
+
7
+ Powers millions of production agents at [Botpress](https://botpress.com).
8
+
9
+ | | |
10
+ | --- | ----------------------------------------------------------------------------------------- |
11
+ | 📚 | [**Examples →**](https://github.com/botpress/botpress/tree/master/packages/llmz/examples) |
4
12
 
5
13
  ---
6
14
 
7
- LLMz is the revolutionary framework behind [Botpress](https://botpress.com), empowering millions of AI agents across thousands of use cases worldwide. Unlike traditional tool-calling frameworks, LLMz leverages the massive body of TypeScript knowledge within LLMs, enabling agents to handle complex logic, loops, conditionals, and multi-tool orchestration seamlessly.
15
+ ## The Problem with Tool Calling
8
16
 
9
- **Stop chaining tools. Start generating real code.**
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.
10
34
 
11
35
  ---
12
36
 
13
- ## 📦 Quick Start
37
+ ## The LLMz Solution
38
+
39
+ LLMz generates and executes **real TypeScript code** in a secure sandbox:
14
40
 
15
- Install and start building agents in seconds:
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
+ return { action: 'done', result: ticketId }
50
+ ```
51
+
52
+ **Why this works:**
53
+
54
+ - LLMs have seen billions of lines of TypeScript—they're exceptionally good at it
55
+ - Complex logic (loops, conditionals, error handling) happens in one inference
56
+ - Multiple tool calls execute synchronously without LLM roundtrips
57
+ - Full type safety via Zui schemas and TypeScript inference
58
+
59
+ **Real-world impact**: Anthropic reduced agent costs by 98.7% using code execution patterns ([source](https://www.anthropic.com/engineering/code-execution-with-mcp)).
60
+
61
+ ---
62
+
63
+ ## Quick Start
64
+
65
+ **Requirements:** Node.js 20+
16
66
 
17
67
  ```bash
18
68
  npm install @botpress/client llmz
19
69
  ```
20
70
 
21
- ### Example
71
+ ### Platform Support
72
+
73
+ | Platform | Support | Notes |
74
+ | ----------- | --------- | --------------------------------------- |
75
+ | Node.js 20+ | Full | Includes isolated VM sandbox |
76
+ | Browser | Partial\* | No sandbox (uses standard JS execution) |
77
+ | Bun | Partial\* | No sandbox (uses standard JS execution) |
78
+ | Deno | Partial\* | No sandbox (uses standard JS execution) |
79
+
80
+ \* A WASM-based sandbox (QuickJS) is in progress and coming soon, which will provide full sandboxed execution for Browser, Bun, and Deno environments.
81
+
82
+ ### Worker Mode: Autonomous Execution
22
83
 
23
84
  ```typescript
24
85
  import { Client } from '@botpress/client'
@@ -27,67 +88,400 @@ import { execute } from 'llmz'
27
88
  const client = new Client({ botId: '...', token: '...' })
28
89
 
29
90
  const result = await execute({
30
- instructions: 'What is the sum of integers between 14 and 1078 divisible by 3, 9, or 5?',
91
+ instructions: 'Calculate sum of integers 14-1078 divisible by 3, 9, or 5',
31
92
  client,
32
93
  })
33
94
 
34
95
  console.log(result.output) // 271575
35
96
  ```
36
97
 
37
- **Instruction:**
98
+ **Generated code:**
38
99
 
39
100
  ```typescript
40
- 'What is the sum of integers between 14 and 1078 divisible by 3, 9, or 5?'
101
+ let sum = 0
102
+ for (let i = 14; i <= 1078; i++) {
103
+ if (i % 3 === 0 || i % 9 === 0 || i % 5 === 0) {
104
+ sum += i
105
+ }
106
+ }
107
+ return { action: 'done', value: { success: true, result: sum } }
41
108
  ```
42
109
 
43
- **LLMz generates and safely executes real TypeScript:**
110
+ ### Chat Mode: Interactive Agents
44
111
 
45
112
  ```typescript
46
- // Calculating the sum of all integers between 14 and 1078 divisible by 3, 9 or 5
47
- let sum = 0
113
+ import { execute } from 'llmz'
114
+ import { Text, Button } from './components'
48
115
 
49
- // Loop through numbers between 14 and 1078 (inclusive)
50
- for (let i = 14; i <= 1078; i++) {
51
- if (i % 3 === 0 || i % 9 === 0 || i % 5 === 0) {
52
- sum += i // Add to sum if divisible by 3, 9, or 5
116
+ const tools = [searchFlights, bookTicket, cancelBooking]
117
+
118
+ let state = { transcript: [] }
119
+
120
+ while (true) {
121
+ const result = await execute({
122
+ client,
123
+ tools,
124
+ chat: {
125
+ transcript: state.transcript,
126
+ components: { Text, Button },
127
+ },
128
+ })
129
+
130
+ if (result.is('listen')) {
131
+ // Agent yielded UI and is waiting for user input
132
+ console.log('Agent:', result.value.components)
133
+ const userInput = await getUserInput()
134
+ state.transcript.push({ role: 'user', content: userInput })
135
+ } else {
136
+ // Agent completed the task
137
+ break
53
138
  }
54
139
  }
140
+ ```
55
141
 
56
- // Return the final result
57
- return { action: 'done', value: { success: true, result: sum } }
142
+ **Generated code:**
143
+
144
+ ```typescript
145
+ const flights = await searchFlights({ from: 'SFO', to: 'NYC' })
146
+
147
+ yield (
148
+ <Text>
149
+ Found {flights.length} flights. Cheapest is ${flights[0].price}. Book it?
150
+ </Text>
151
+ )
152
+ yield <Button>Book Flight</Button>
153
+ yield <Button>Cancel</Button>
154
+
155
+ return { action: 'listen' }
58
156
  ```
59
157
 
60
- **Result:**
158
+ ---
159
+
160
+ ## Core Concepts
61
161
 
62
- ```json
63
- { "success": true, "result": 271575 }
162
+ ### Execution Modes
163
+
164
+ **Worker Mode**: Autonomous agents that execute to completion
165
+
166
+ ```typescript
167
+ const result = await execute({
168
+ instructions: 'Analyze Q4 sales data and generate report',
169
+ client,
170
+ tools: [fetchSales, calculateMetrics, generatePDF],
171
+ })
172
+ ```
173
+
174
+ **Chat Mode**: Interactive conversations with user input
175
+
176
+ ```typescript
177
+ const result = await execute({
178
+ client,
179
+ tools,
180
+ chat: {
181
+ transcript: conversationHistory,
182
+ components: { Text, Button, Form },
183
+ },
184
+ })
64
185
  ```
65
186
 
187
+ ### Tools: Type-Safe Functions
188
+
189
+ ```typescript
190
+ import { Tool } from 'llmz'
191
+ import { z } from '@bpinternal/zui'
192
+
193
+ const searchFlights = new Tool({
194
+ name: 'searchFlights',
195
+ description: 'Search for available flights',
196
+ input: z.object({
197
+ from: z.string(),
198
+ to: z.string(),
199
+ date: z.string(),
200
+ }),
201
+ output: z.array(
202
+ z.object({
203
+ id: z.string(),
204
+ price: z.number(),
205
+ departure: z.string(),
206
+ })
207
+ ),
208
+ handler: async ({ from, to, date }) => {
209
+ // Your implementation
210
+ return flights
211
+ },
212
+ })
213
+ ```
214
+
215
+ Tools are exposed to agents with full TypeScript signatures. Agents call them like regular async functions.
216
+
217
+ ### Objects: Namespaced State
218
+
219
+ Group related tools and variables:
220
+
221
+ ```typescript
222
+ import { ObjectInstance } from 'llmz'
223
+ import { z } from '@bpinternal/zui'
224
+
225
+ const database = new ObjectInstance({
226
+ name: 'db',
227
+ description: 'Database operations',
228
+ tools: [queryUsers, updateRecord, deleteRecord],
229
+ properties: [
230
+ {
231
+ name: 'connectionString',
232
+ value: process.env.DB_URL,
233
+ writable: false,
234
+ },
235
+ {
236
+ name: 'lastQueryTime',
237
+ value: null,
238
+ type: z.string().nullable(),
239
+ writable: true,
240
+ },
241
+ ],
242
+ })
243
+ ```
244
+
245
+ Agents access via namespaces:
246
+
247
+ ```typescript
248
+ const users = await db.queryUsers({ active: true })
249
+ db.lastQueryTime = new Date().toISOString()
250
+ ```
251
+
252
+ ### Exits: Structured Termination
253
+
254
+ Define how agents can complete:
255
+
256
+ ```typescript
257
+ import { Exit } from 'llmz'
258
+ import { z } from '@bpinternal/zui'
259
+
260
+ const TicketBooked = new Exit({
261
+ name: 'ticket_booked',
262
+ description: 'Successfully booked a ticket',
263
+ schema: z.object({
264
+ ticketId: z.string(),
265
+ price: z.number(),
266
+ confirmation: z.string(),
267
+ }),
268
+ })
269
+
270
+ const result = await execute({
271
+ client,
272
+ tools,
273
+ exits: [TicketBooked],
274
+ })
275
+
276
+ if (result.is(TicketBooked)) {
277
+ console.log('Booked:', result.value.ticketId) // Fully typed
278
+ }
279
+ ```
280
+
281
+ Agents use exits via return statements:
282
+
283
+ ```typescript
284
+ return {
285
+ action: 'ticket_booked',
286
+ ticketId: 'TKT-12345',
287
+ price: 299,
288
+ confirmation: 'ABC123',
289
+ }
290
+ ```
291
+
292
+ ---
293
+
294
+ ## Advanced Features
295
+
296
+ ### Thinking: Forced Reflection
297
+
298
+ Prevent agents from rushing to conclusions:
299
+
300
+ ```typescript
301
+ import { ThinkSignal } from 'llmz'
302
+
303
+ const complexAnalysis = new Tool({
304
+ name: 'analyze',
305
+ handler: async (data) => {
306
+ const result = performComplexCalculation(data)
307
+ // Force agent to reflect on results before proceeding
308
+ throw new ThinkSignal('Analysis complete. Review data before next step.')
309
+ },
310
+ })
311
+ ```
312
+
313
+ Agents can also self-initiate thinking:
314
+
315
+ ```typescript
316
+ // Agent-generated code
317
+ const data = await fetchLargeDataset()
318
+ return { action: 'think' } // Pause to process information
319
+ ```
320
+
321
+ ### Snapshots: Pause and Resume
322
+
323
+ Save execution state for long-running workflows:
324
+
325
+ ```typescript
326
+ import { SnapshotSignal } from 'llmz'
327
+
328
+ const approvalRequired = new Tool({
329
+ name: 'submitForApproval',
330
+ handler: async (request) => {
331
+ await saveToDatabase(request)
332
+ // Halt execution until manual approval
333
+ throw new SnapshotSignal('Awaiting manager approval')
334
+ },
335
+ })
336
+
337
+ // Later, resume from snapshot
338
+ const result = await execute({
339
+ client,
340
+ snapshot: savedSnapshot,
341
+ })
342
+ ```
343
+
344
+ ### Hooks: Custom Logic Injection
345
+
346
+ ```typescript
347
+ const result = await execute({
348
+ client,
349
+ tools,
350
+ hooks: {
351
+ onTrace: (trace) => {
352
+ // Non-blocking: log tool calls, errors, outputs
353
+ logger.info(trace)
354
+ },
355
+ onExit: (exit) => {
356
+ // Validate before allowing exit
357
+ if (exit.action === 'transfer_money' && exit.amount > 10000) {
358
+ throw new Error('Amount exceeds limit')
359
+ }
360
+ },
361
+ onBeforeExecution: (code) => {
362
+ // Inspect/modify generated code before execution
363
+ if (code.includes('dangerousOperation')) {
364
+ throw new Error('Blocked unsafe operation')
365
+ }
366
+ },
367
+ },
368
+ })
369
+ ```
370
+
371
+ ---
372
+
373
+ ## Coming from MCP?
374
+
375
+ LLMz is **not** a replacement for MCP—it's complementary.
376
+
377
+ **MCP** (Model Context Protocol): Standardizes how AI applications connect to data sources and tools across processes/machines.
378
+
379
+ **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%.
380
+
381
+ ---
382
+
383
+ ## Production Ready
384
+
385
+ LLMz has been running in production for over a year:
386
+
387
+ - **Millions** of active users across enterprise and consumer applications
388
+ - **Hundreds of thousands** of deployed agents handling real-world workloads
389
+ - **Secure sandbox**: Uses `isolated-vm` for untrusted code execution
390
+ - **Type-safe**: Full TypeScript inference and Zui validation
391
+ - **Observable**: Comprehensive tracing and error handling
392
+
393
+ ---
394
+
395
+ ## Architecture
396
+
397
+ **Execution Pipeline:**
398
+
399
+ 1. **Prompt Generation**: Injects tools, schemas, and context into dual-mode prompts
400
+ 2. **Code Generation**: LLM generates TypeScript with tool calls and logic
401
+ 3. **Compilation**: Babel AST transformation with custom plugins (tracking, JSX, source maps)
402
+ 4. **Execution**: Runs in isolated VM (production) or Node.js VM (development)
403
+ 5. **Result Processing**: Type-safe exit handling and error recovery
404
+
405
+ **Security:**
406
+
407
+ - Sandboxed execution environment (no filesystem/network access)
408
+ - Stack trace sanitization (removes internal framework details)
409
+ - Configurable tool permissions and rate limiting
410
+ - Automatic token limit handling
411
+
412
+ ---
413
+
414
+ ## Comparison
415
+
416
+ | Feature | LangChain / CrewAI | MCP Servers | LLMz |
417
+ | ------------------------ | ---------------------- | ---------------------- | ------------------------- |
418
+ | Tool calling | JSON | JSON | TypeScript code |
419
+ | Multi-tool orchestration | Multiple LLM calls | Multiple LLM calls | Single LLM call |
420
+ | Complex logic | Limited | Limited | Full language support |
421
+ | Type safety | Partial | Schema-based | Full TypeScript + Zui |
422
+ | Execution environment | Python/JS runtime | Cross-process | Isolated VM |
423
+ | Cost (complex workflows) | High (many roundtrips) | High (many roundtrips) | Low (one-shot generation) |
424
+ | Production scale | Varies | Emerging | Battle-tested (1M+ users) |
425
+
66
426
  ---
67
427
 
68
- ## ⚡ Why LLMz Beats JSON Tool Calling
428
+ ## Examples
69
429
 
70
- ### Traditional JSON Tool Calling
430
+ Check out the [examples folder](https://github.com/botpress/botpress/tree/master/packages/llmz/examples) for complete working examples:
71
431
 
72
- - Hard-to-parse JSON schemas for LLMs
73
- - Incapable of complex logic, loops, and conditionals
74
- - Multiple expensive roundtrips for each tool call
75
- - Unreliable beyond simple scenarios
432
+ | Title | Mode | Description |
433
+ | --------------------------------------------------------------------------------------------------------------------- | ------ | ---------------------------------------------------- |
434
+ | [Basic Chat](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/01_chat_basic) | Chat | Simple interactive chat with button-based navigation |
435
+ | [Chat with Exits](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/02_chat_exits) | Chat | Custom exit conditions with type-safe validation |
436
+ | [Conditional Tools](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/03_chat_conditional_tool) | Chat | Dynamic tool availability based on context |
437
+ | [Small Models](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/04_chat_small_models) | Chat | Optimized prompts for smaller language models |
438
+ | [Web Search](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/05_chat_web_search) | Chat | Integrate web search and content browsing |
439
+ | [Tool Confirmation](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/06_chat_confirm_tool) | Chat | User confirmation before executing tools |
440
+ | [Guardrails](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/07_chat_guardrails) | Chat | Safety constraints and content filtering |
441
+ | [Multi-Agent](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/08_chat_multi_agent) | Chat | Coordinating multiple agents in one system |
442
+ | [Variables](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/09_chat_variables) | Chat | Stateful properties that persist across iterations |
443
+ | [Components](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/10_chat_components) | Chat | Rich UI components for interactive experiences |
444
+ | [Minimal Worker](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/11_worker_minimal) | Worker | One-shot computational task execution |
445
+ | [File System](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/12_worker_fs) | Worker | Automated file operations with conditional logic |
446
+ | [Sandbox](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/13_worker_sandbox) | Worker | Secure isolated code execution environment |
447
+ | [Snapshots](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/14_worker_snapshot) | Worker | Pause and resume long-running workflows |
448
+ | [Stack Traces](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/15_worker_stacktraces) | Worker | Error handling and debugging patterns |
449
+ | [Tool Chaining](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/16_worker_tool_chaining) | Worker | Sequential multi-tool orchestration |
450
+ | [Error Recovery](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/17_worker_error_recovery) | Worker | Graceful failure handling and retries |
451
+ | [Security](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/18_worker_security) | Worker | Code inspection and security validation |
452
+ | [Wrap Tools](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/19_worker_wrap_tool) | Worker | Creating higher-order tool abstractions |
453
+ | [RAG](https://github.com/botpress/botpress/tree/master/packages/llmz/examples/20_chat_rag) | Chat | Retrieval-augmented generation with knowledge bases |
76
454
 
77
- ### LLMz TypeScript Generation ✅
455
+ ---
456
+
457
+ ## Contributing
458
+
459
+ ```bash
460
+ git clone https://github.com/botpress/botpress
461
+ cd packages/llmz
462
+
463
+ pnpm install
464
+ pnpm test
465
+ pnpm build
466
+ ```
467
+
468
+ **Commands:**
78
469
 
79
- - **Billions** of lines of TypeScript training data
80
- - Native LLM thinking via comments and code structure
81
- - Complex logic and multi-tool orchestration in **one call**
82
- - Complete type safety and predictable schemas
83
- - Scales effortlessly in production
470
+ - `pnpm test`: Run test suite (Vitest with LLM retries)
471
+ - `pnpm test:watch`: Watch mode for development
472
+ - `pnpm build`: Compile TypeScript and bundle (ESM + CJS)
473
+ - `pnpm generate`: Regenerate prompt templates from markdown
84
474
 
85
475
  ---
86
476
 
87
- ## 🌟 Battle-Tested at Massive Scale
477
+ ## License
478
+
479
+ MIT
480
+
481
+ ---
88
482
 
89
- LLMz isn't experimental. It's been driving production workloads globally:
483
+ ## Learn More
90
484
 
91
- - **1+ year** in production
92
- - **Millions** of active users
93
- - **Hundreds of thousands** of deployed agents
485
+ - [Anthropic: Code Execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp)
486
+ - [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)
487
+ - [Botpress Documentation](https://botpress.com/docs)
@@ -2031,19 +2031,59 @@ function escapeBracesInCodeFences(tsx) {
2031
2031
  let i = 0;
2032
2032
  let output = "";
2033
2033
  let insideFencedBlock = false;
2034
+ let jsxDepth = 0;
2035
+ let braceDepth = 0;
2034
2036
  while (i < tsx.length) {
2037
+ const char = tsx[i];
2038
+ if (char === "<" && !insideFencedBlock) {
2039
+ if (tsx[i + 1] !== "/") {
2040
+ jsxDepth++;
2041
+ } else {
2042
+ jsxDepth--;
2043
+ }
2044
+ output += char;
2045
+ i++;
2046
+ continue;
2047
+ }
2048
+ if (jsxDepth > 0 && !insideFencedBlock) {
2049
+ if (char === "{") {
2050
+ braceDepth++;
2051
+ output += char;
2052
+ i++;
2053
+ continue;
2054
+ } else if (char === "}") {
2055
+ braceDepth--;
2056
+ output += char;
2057
+ i++;
2058
+ continue;
2059
+ }
2060
+ }
2035
2061
  if (tsx.startsWith("```", i)) {
2036
2062
  insideFencedBlock = !insideFencedBlock;
2037
2063
  output += "```";
2038
2064
  i += 3;
2039
2065
  continue;
2040
2066
  }
2041
- if (insideFencedBlock && tsx[i] in HTML_ENTITIES) {
2042
- output += HTML_ENTITIES[tsx[i]];
2067
+ if (jsxDepth > 0 && braceDepth === 0 && !insideFencedBlock && char === "`") {
2068
+ const closingIndex = tsx.indexOf("`", i + 1);
2069
+ if (closingIndex !== -1) {
2070
+ const inlineCode = tsx.slice(i + 1, closingIndex);
2071
+ let escaped = "`";
2072
+ for (const c of inlineCode) {
2073
+ escaped += HTML_ENTITIES[c] || c;
2074
+ }
2075
+ escaped += "`";
2076
+ output += escaped;
2077
+ i = closingIndex + 1;
2078
+ continue;
2079
+ }
2080
+ }
2081
+ if (insideFencedBlock && char in HTML_ENTITIES) {
2082
+ output += HTML_ENTITIES[char];
2043
2083
  i++;
2044
2084
  continue;
2045
2085
  }
2046
- output += tsx[i];
2086
+ output += char;
2047
2087
  i++;
2048
2088
  }
2049
2089
  return output;
@@ -2031,19 +2031,59 @@ function escapeBracesInCodeFences(tsx) {
2031
2031
  let i = 0;
2032
2032
  let output = "";
2033
2033
  let insideFencedBlock = false;
2034
+ let jsxDepth = 0;
2035
+ let braceDepth = 0;
2034
2036
  while (i < tsx.length) {
2037
+ const char = tsx[i];
2038
+ if (char === "<" && !insideFencedBlock) {
2039
+ if (tsx[i + 1] !== "/") {
2040
+ jsxDepth++;
2041
+ } else {
2042
+ jsxDepth--;
2043
+ }
2044
+ output += char;
2045
+ i++;
2046
+ continue;
2047
+ }
2048
+ if (jsxDepth > 0 && !insideFencedBlock) {
2049
+ if (char === "{") {
2050
+ braceDepth++;
2051
+ output += char;
2052
+ i++;
2053
+ continue;
2054
+ } else if (char === "}") {
2055
+ braceDepth--;
2056
+ output += char;
2057
+ i++;
2058
+ continue;
2059
+ }
2060
+ }
2035
2061
  if (tsx.startsWith("```", i)) {
2036
2062
  insideFencedBlock = !insideFencedBlock;
2037
2063
  output += "```";
2038
2064
  i += 3;
2039
2065
  continue;
2040
2066
  }
2041
- if (insideFencedBlock && tsx[i] in HTML_ENTITIES) {
2042
- output += HTML_ENTITIES[tsx[i]];
2067
+ if (jsxDepth > 0 && braceDepth === 0 && !insideFencedBlock && char === "`") {
2068
+ const closingIndex = tsx.indexOf("`", i + 1);
2069
+ if (closingIndex !== -1) {
2070
+ const inlineCode = tsx.slice(i + 1, closingIndex);
2071
+ let escaped = "`";
2072
+ for (const c of inlineCode) {
2073
+ escaped += HTML_ENTITIES[c] || c;
2074
+ }
2075
+ escaped += "`";
2076
+ output += escaped;
2077
+ i = closingIndex + 1;
2078
+ continue;
2079
+ }
2080
+ }
2081
+ if (insideFencedBlock && char in HTML_ENTITIES) {
2082
+ output += HTML_ENTITIES[char];
2043
2083
  i++;
2044
2084
  continue;
2045
2085
  }
2046
- output += tsx[i];
2086
+ output += char;
2047
2087
  i++;
2048
2088
  }
2049
2089
  return output;
package/dist/index.cjs CHANGED
@@ -1103,16 +1103,16 @@ var utils = {
1103
1103
  truncateWrappedContent: _chunkGZPN7RGHcjs.truncateWrappedContent
1104
1104
  };
1105
1105
  var execute = async (props) => {
1106
- const { executeContext } = await Promise.resolve().then(() => _interopRequireWildcard(require("./llmz-M7XYQZT7.cjs")));
1106
+ const { executeContext } = await Promise.resolve().then(() => _interopRequireWildcard(require("./llmz-RZUY2RT4.cjs")));
1107
1107
  return executeContext(props);
1108
1108
  };
1109
1109
  var init = async () => {
1110
- await Promise.resolve().then(() => _interopRequireWildcard(require("./llmz-M7XYQZT7.cjs")));
1110
+ await Promise.resolve().then(() => _interopRequireWildcard(require("./llmz-RZUY2RT4.cjs")));
1111
1111
  await Promise.resolve().then(() => _interopRequireWildcard(require("./component-R4WTW6DZ.cjs")));
1112
1112
  await Promise.resolve().then(() => _interopRequireWildcard(require("./tool-GMYMVXUK.cjs")));
1113
1113
  await Promise.resolve().then(() => _interopRequireWildcard(require("./exit-XAYKJ6TR.cjs")));
1114
1114
  await Promise.resolve().then(() => _interopRequireWildcard(require("./jsx-AJAXBWFE.cjs")));
1115
- await Promise.resolve().then(() => _interopRequireWildcard(require("./vm-YJX6M4NJ.cjs")));
1115
+ await Promise.resolve().then(() => _interopRequireWildcard(require("./vm-5SJN3OJI.cjs")));
1116
1116
  await Promise.resolve().then(() => _interopRequireWildcard(require("./utils-L5QAQXV2.cjs")));
1117
1117
  await Promise.resolve().then(() => _interopRequireWildcard(require("./truncator-W3NXBLYJ.cjs")));
1118
1118
  await Promise.resolve().then(() => _interopRequireWildcard(require("./typings-2RAAZ2YP.cjs")));
package/dist/index.js CHANGED
@@ -1103,16 +1103,16 @@ var utils = {
1103
1103
  truncateWrappedContent
1104
1104
  };
1105
1105
  var execute = async (props) => {
1106
- const { executeContext } = await import("./llmz-WPO4HYQY.js");
1106
+ const { executeContext } = await import("./llmz-QUBEO7EF.js");
1107
1107
  return executeContext(props);
1108
1108
  };
1109
1109
  var init = async () => {
1110
- await import("./llmz-WPO4HYQY.js");
1110
+ await import("./llmz-QUBEO7EF.js");
1111
1111
  await import("./component-WFVDVSDK.js");
1112
1112
  await import("./tool-GEBXW6AQ.js");
1113
1113
  await import("./exit-YLO7BY7Z.js");
1114
1114
  await import("./jsx-AEHVFB3L.js");
1115
- await import("./vm-I4G4IH7T.js");
1115
+ await import("./vm-SQHETBVH.js");
1116
1116
  await import("./utils-RQHQ2KOG.js");
1117
1117
  await import("./truncator-BSP6PQPC.js");
1118
1118
  await import("./typings-3VYUEACY.js");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runAsyncFunction
3
- } from "./chunk-7G5QAIUX.js";
3
+ } from "./chunk-ERK3MOZF.js";
4
4
  import {
5
5
  Context,
6
6
  ErrorExecutionResult,
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
2
 
3
- var _chunkM3LCKL55cjs = require('./chunk-M3LCKL55.cjs');
3
+ var _chunkFMOTPO76cjs = require('./chunk-FMOTPO76.cjs');
4
4
 
5
5
 
6
6
 
@@ -362,7 +362,7 @@ var executeIteration = async ({
362
362
  });
363
363
  }
364
364
  startedAt = Date.now();
365
- const result = await _chunkM3LCKL55cjs.runAsyncFunction.call(void 0,
365
+ const result = await _chunkFMOTPO76cjs.runAsyncFunction.call(void 0,
366
366
  vmContext,
367
367
  iteration.code,
368
368
  traces,
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkM3LCKL55cjs = require('./chunk-M3LCKL55.cjs');
4
+ var _chunkFMOTPO76cjs = require('./chunk-FMOTPO76.cjs');
5
5
  require('./chunk-T63Y6GTW.cjs');
6
6
  require('./chunk-KIN7Y247.cjs');
7
7
  require('./chunk-KMZDFWYZ.cjs');
@@ -9,4 +9,4 @@ require('./chunk-UQOBUJIQ.cjs');
9
9
 
10
10
 
11
11
 
12
- exports.CAN_USE_ISOLATED_VM = _chunkM3LCKL55cjs.CAN_USE_ISOLATED_VM; exports.runAsyncFunction = _chunkM3LCKL55cjs.runAsyncFunction;
12
+ exports.CAN_USE_ISOLATED_VM = _chunkFMOTPO76cjs.CAN_USE_ISOLATED_VM; exports.runAsyncFunction = _chunkFMOTPO76cjs.runAsyncFunction;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CAN_USE_ISOLATED_VM,
3
3
  runAsyncFunction
4
- } from "./chunk-7G5QAIUX.js";
4
+ } from "./chunk-ERK3MOZF.js";
5
5
  import "./chunk-MYLTD5WT.js";
6
6
  import "./chunk-YEAWWJSJ.js";
7
7
  import "./chunk-ORQP26SZ.js";
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "llmz",
3
3
  "type": "module",
4
4
  "description": "LLMz – An LLM-native Typescript VM built on top of Zui",
5
- "version": "0.0.28",
5
+ "version": "0.0.29",
6
6
  "types": "./dist/index.d.ts",
7
7
  "main": "./dist/index.cjs",
8
8
  "module": "./dist/index.js",