llmz 0.8.0 → 0.9.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 (68) hide show
  1. package/README.md +45 -11
  2. package/dist/chat.d.ts +6 -6
  3. package/dist/{common-DdArNQhl.cjs → common-DJkSpeqw.cjs} +239 -22
  4. package/dist/{common-pgJjFu2Y.js → common-DuEhn6u3.js} +234 -23
  5. package/dist/compiler/plugins/variable-extraction.d.ts +1 -7
  6. package/dist/{compiler-C-OI9sim.cjs → compiler-BJJUmNS9.cjs} +34 -68
  7. package/dist/{compiler-CW1VjQsn.js → compiler-BPl-5CXh.js} +34 -68
  8. package/dist/{component-BXS8vAwO.cjs → component-CPKXe6Ca.cjs} +2 -2
  9. package/dist/{component-Dq7ZLdvy.js → component-DGG7d_Mz.js} +1 -1
  10. package/dist/component.default.d.ts +10 -0
  11. package/dist/context.d.ts +4 -8
  12. package/dist/{custom-client-HkM1Sdzv.cjs → custom-client-B_o56CB4.cjs} +22 -19
  13. package/dist/{custom-client-2V9lmzUf.js → custom-client-C-nDKG37.js} +17 -14
  14. package/dist/{dual-modes-Cb7ThvoV.cjs → dual-modes-BNHlj2qM.cjs} +1252 -1181
  15. package/dist/{dual-modes-Cy0_W4O2.js → dual-modes-BNIiNLrR.js} +1257 -1180
  16. package/dist/example-format.d.ts +8 -0
  17. package/dist/{execute-COIHOIKR.cjs → execute-0bvqakr7.cjs} +91 -99
  18. package/dist/{execute-Aw4cbIx-.js → execute-CWFIL5ny.js} +91 -99
  19. package/dist/{exit-DUM96DN1.cjs → exit-CGLXI0BH.cjs} +2 -2
  20. package/dist/index.cjs +265 -22
  21. package/dist/index.js +258 -15
  22. package/dist/index.workerd.js +8565 -8005
  23. package/dist/inspect.d.ts +2 -0
  24. package/dist/isPlainObject-CSxXVKCk.cjs +56 -0
  25. package/dist/isPlainObject-D39AzPO2.js +51 -0
  26. package/dist/{jsx-D5Y2cPo-.cjs → jsx-BJ6GWXI2.cjs} +3 -57
  27. package/dist/{jsx-B0iYyvfr.js → jsx-CIgdGGVs.js} +2 -50
  28. package/dist/message-stream/instructions.d.ts +8 -0
  29. package/dist/message-stream/parser.d.ts +6 -0
  30. package/dist/message-stream/response-parser.d.ts +24 -0
  31. package/dist/message-stream/response-parser.test.d.ts +1 -0
  32. package/dist/message-stream/types.d.ts +3 -2
  33. package/dist/prompts/adherence.test.d.ts +1 -0
  34. package/dist/prompts/catalogue-examples.test.d.ts +1 -0
  35. package/dist/prompts/chat-mode/protocol.d.ts +2 -0
  36. package/dist/prompts/chat-mode/system.d.ts +1 -1
  37. package/dist/prompts/chat-mode/user.d.ts +1 -1
  38. package/dist/prompts/code-examples.d.ts +2 -0
  39. package/dist/prompts/code-examples.test.d.ts +1 -0
  40. package/dist/prompts/common.d.ts +2 -1
  41. package/dist/prompts/concrete-patterns.test.d.ts +1 -0
  42. package/dist/prompts/long-search.test.d.ts +1 -0
  43. package/dist/prompts/prompt.d.ts +5 -2
  44. package/dist/prompts/protocol-basics.d.ts +5 -0
  45. package/dist/prompts/protocol-simple.test.d.ts +1 -0
  46. package/dist/prompts/protocol.d.ts +13 -0
  47. package/dist/prompts/sections.test.d.ts +1 -0
  48. package/dist/prompts/worker-mode/protocol.d.ts +2 -0
  49. package/dist/prompts/worker-mode/system.d.ts +1 -1
  50. package/dist/prompts/worker-mode/user.d.ts +1 -1
  51. package/dist/runtime/citations.test.d.ts +1 -0
  52. package/dist/runtime/fixtures/long-search.d.ts +19 -0
  53. package/dist/runtime/fixtures/protocol-languages.d.ts +74 -0
  54. package/dist/runtime/fixtures/qwen-protocol-failures.d.ts +29 -0
  55. package/dist/runtime/generate.d.ts +2 -9
  56. package/dist/runtime/generate.test.d.ts +1 -0
  57. package/dist/runtime/protocol-adherence.test.d.ts +1 -0
  58. package/dist/runtime/types.d.ts +4 -7
  59. package/dist/{tool-Bv8N4IPj.js → tool-B6Pmuk6K.js} +35 -49
  60. package/dist/{tool-Dy6AJpJH.cjs → tool-BLTrA-sL.cjs} +38 -52
  61. package/dist/tool.d.ts +5 -3
  62. package/dist/{truncator-DZqEqnpD.js → truncator-CD7QtE84.js} +11 -6
  63. package/dist/{truncator-CLkouTCO.cjs → truncator-DmCu9M4m.cjs} +13 -8
  64. package/dist/{typings-3lsqCbkn.cjs → typings-DXJMu59O.cjs} +2 -2
  65. package/dist/{utils-3ESwP3yg.cjs → utils-DGQ4sRke.cjs} +1 -1
  66. package/dist/{vm-BLsHw1da.js → vm-Cn3jvZ00.js} +109 -53
  67. package/dist/{vm-D6s1zF6M.cjs → vm-X0uTj5Aa.cjs} +109 -53
  68. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.js";
2
- import { r as hasTopLevelReturn } from "./compiler-CW1VjQsn.js";
2
+ import { r as hasTopLevelReturn } from "./compiler-BPl-5CXh.js";
3
3
  import JSON5 from "json5";
4
4
  import { jsonrepair } from "jsonrepair";
5
5
  //#region src/message-stream/types.ts
@@ -63,6 +63,7 @@ var StreamingMessageParser = class {
63
63
  _currentReady = false;
64
64
  _counter = 0;
65
65
  _finished = false;
66
+ _ended = false;
66
67
  _directiveBuffer = "";
67
68
  _nameBuffer = "";
68
69
  _propsBuffer = "";
@@ -74,6 +75,8 @@ var StreamingMessageParser = class {
74
75
  _pendingWhitespace = "";
75
76
  _preambleHeader;
76
77
  _closingFenceTicks;
78
+ _lineStart = true;
79
+ _exampleDelimiter = "";
77
80
  constructor(options = {}) {
78
81
  this._maxPropsLength = options.maxPropsLength ?? 1e5;
79
82
  }
@@ -88,7 +91,7 @@ var StreamingMessageParser = class {
88
91
  push(chunk) {
89
92
  if (this._finished) throw new Error("Parser has already finished. Call reset() before parsing a new stream.");
90
93
  const events = [];
91
- for (const char of chunk) this._processChar(char, events);
94
+ for (const char of chunk) this._processOutputChar(char, events);
92
95
  this._flushBodyDelta(events);
93
96
  return events;
94
97
  }
@@ -102,6 +105,9 @@ var StreamingMessageParser = class {
102
105
  if (this._finished) return [];
103
106
  this._finished = true;
104
107
  const events = [];
108
+ if (/^"""\s*$/.test(this._exampleDelimiter)) this._discardExampleDelimiter(events);
109
+ else if (reason === "end") this._flushExampleDelimiter(events);
110
+ else this._exampleDelimiter = "";
105
111
  if (this._closingFenceTicks !== void 0 && this._closingFenceTicks !== 3) this._skipUnexpectedText(events);
106
112
  this._closingFenceTicks = void 0;
107
113
  const status = reason === "interrupted" ? "interrupted" : void 0;
@@ -138,6 +144,7 @@ var StreamingMessageParser = class {
138
144
  this._currentReady = false;
139
145
  this._counter = 0;
140
146
  this._finished = false;
147
+ this._ended = false;
141
148
  this._directiveBuffer = "";
142
149
  this._nameBuffer = "";
143
150
  this._propsBuffer = "";
@@ -149,6 +156,50 @@ var StreamingMessageParser = class {
149
156
  this._pendingWhitespace = "";
150
157
  this._preambleHeader = void 0;
151
158
  this._closingFenceTicks = void 0;
159
+ this._lineStart = true;
160
+ this._exampleDelimiter = "";
161
+ }
162
+ _processOutputChar(char, events) {
163
+ const lineStart = this._lineStart;
164
+ this._lineStart = char === "\n" || lineStart && (char === " " || char === " " || char === "\r");
165
+ if (this._exampleDelimiter) {
166
+ if (this._exampleDelimiter.includes("\n")) {
167
+ if (isWhitespace(char)) {
168
+ this._exampleDelimiter += char;
169
+ return;
170
+ }
171
+ if (char === "■") this._discardExampleDelimiter(events);
172
+ else this._flushExampleDelimiter(events);
173
+ } else {
174
+ const candidate = this._exampleDelimiter + char;
175
+ if (/^(?:"{1,2}|"""[ \t]*\r?)$/.test(candidate)) {
176
+ this._exampleDelimiter = candidate;
177
+ return;
178
+ }
179
+ if (/^"""[ \t]*\r?\n$/.test(candidate)) {
180
+ this._exampleDelimiter = candidate;
181
+ if (this._state !== "body") this._discardExampleDelimiter(events);
182
+ return;
183
+ }
184
+ this._flushExampleDelimiter(events);
185
+ }
186
+ }
187
+ if (lineStart && char === "\"" && (this._state === "idle" || this._state === "skip" || this._state === "body-wait" || this._state === "body")) {
188
+ this._exampleDelimiter = char;
189
+ return;
190
+ }
191
+ this._processChar(char, events);
192
+ }
193
+ _flushExampleDelimiter(events) {
194
+ for (const char of this._exampleDelimiter) this._processChar(char, events);
195
+ this._exampleDelimiter = "";
196
+ }
197
+ _discardExampleDelimiter(events) {
198
+ this._exampleDelimiter = "";
199
+ this._diagnostic(events, {
200
+ code: "example-delimiter",
201
+ message: "Discarded a triple-quote example delimiter"
202
+ });
152
203
  }
153
204
  _processChar(char, events) {
154
205
  if (this._closingFenceTicks !== void 0) {
@@ -160,9 +211,18 @@ var StreamingMessageParser = class {
160
211
  this._closingFenceTicks = void 0;
161
212
  this._skipUnexpectedText(events);
162
213
  }
214
+ if (this._ended) {
215
+ if (this._state === "skip" || isWhitespace(char)) return;
216
+ if (char === "`") {
217
+ this._closingFenceTicks = 1;
218
+ return;
219
+ }
220
+ this._skipUnexpectedText(events);
221
+ return;
222
+ }
163
223
  switch (this._state) {
164
224
  case "idle":
165
- if (char === "■") this._beginItem();
225
+ if (char === "■") this._beginItem(events);
166
226
  else if (!isWhitespace(char)) {
167
227
  const last = this._items.at(-1);
168
228
  if (char === "`" && (last === null || last === void 0 ? void 0 : last.kind) === "next" && last.status === "complete") {
@@ -178,7 +238,7 @@ var StreamingMessageParser = class {
178
238
  else if (char === "■") {
179
239
  this._endDirective(events, void 0);
180
240
  this._completeCurrent(events);
181
- this._beginItem();
241
+ this._beginItem(events);
182
242
  } else if (char === "\n") this._endDirective(events, "\n");
183
243
  else if (isWhitespace(char)) this._endDirective(events, " ");
184
244
  else if (char === "{") this._endDirective(events, "{");
@@ -188,7 +248,7 @@ var StreamingMessageParser = class {
188
248
  if (char === "■") {
189
249
  this._endName(events);
190
250
  this._completeCurrent(events);
191
- this._beginItem();
251
+ this._beginItem(events);
192
252
  } else if (char === "{") {
193
253
  this._endName(events);
194
254
  this._afterHeaderChar(char, events);
@@ -209,7 +269,7 @@ var StreamingMessageParser = class {
209
269
  case "body-wait":
210
270
  if (char === "■") {
211
271
  this._completeCurrent(events);
212
- this._beginItem();
272
+ this._beginItem(events);
213
273
  } else if (!isWhitespace(char)) {
214
274
  this._startBody(events);
215
275
  this._appendBody(char);
@@ -220,7 +280,7 @@ var StreamingMessageParser = class {
220
280
  this._pendingWhitespace = "";
221
281
  this._flushBodyDelta(events);
222
282
  this._completeCurrent(events);
223
- this._beginItem();
283
+ this._beginItem(events);
224
284
  } else this._appendBody(char);
225
285
  return;
226
286
  case "skip":
@@ -233,7 +293,7 @@ var StreamingMessageParser = class {
233
293
  }
234
294
  return;
235
295
  }
236
- if (char === "■") this._beginItem();
296
+ if (char === "■") this._beginItem(events);
237
297
  return;
238
298
  }
239
299
  }
@@ -250,7 +310,7 @@ var StreamingMessageParser = class {
250
310
  const item = this._current;
251
311
  if (char === "■") {
252
312
  this._completeCurrent(events);
253
- this._beginItem();
313
+ this._beginItem(events);
254
314
  return;
255
315
  }
256
316
  if (char === "{" && (item.kind === "send" || item.kind === "next")) {
@@ -292,7 +352,7 @@ var StreamingMessageParser = class {
292
352
  else if (char === "■" && this._propsBroken) {
293
353
  this._failProps(events, "props were interrupted by a new block");
294
354
  this._completeCurrent(events);
295
- this._beginItem();
355
+ this._beginItem(events);
296
356
  }
297
357
  return;
298
358
  }
@@ -300,14 +360,18 @@ var StreamingMessageParser = class {
300
360
  else if (char === "■") {
301
361
  this._failProps(events, "props were interrupted by a new block");
302
362
  this._completeCurrent(events);
303
- this._beginItem();
363
+ this._beginItem(events);
304
364
  } else if (char === "{" || char === "[") this._propsDepth++;
305
365
  else if (char === "}" || char === "]") {
306
366
  this._propsDepth--;
307
367
  if (this._propsDepth <= 0) this._endProps(events);
308
368
  }
309
369
  }
310
- _beginItem() {
370
+ _beginItem(events) {
371
+ if (this._ended) {
372
+ this._skipUnexpectedText(events);
373
+ return;
374
+ }
311
375
  const item = {
312
376
  id: `item-${this._counter++}`,
313
377
  kind: "unknown",
@@ -506,6 +570,7 @@ var StreamingMessageParser = class {
506
570
  if (!item) return;
507
571
  this._ready(events);
508
572
  if (item.status !== "invalid") item.status = forcedStatus ?? "complete";
573
+ if (item.kind === "next" && item.status === "complete") this._ended = true;
509
574
  events.push({
510
575
  type: "item-complete",
511
576
  item
@@ -516,7 +581,7 @@ var StreamingMessageParser = class {
516
581
  _skipUnexpectedText(events) {
517
582
  this._diagnostic(events, {
518
583
  code: "unexpected-text",
519
- message: "Encountered text outside of a ■ block"
584
+ message: this._ended ? "Discarded content after terminal ■next" : "Encountered text outside of a ■ block"
520
585
  });
521
586
  this._state = "skip";
522
587
  }
@@ -533,17 +598,163 @@ var StreamingMessageParser = class {
533
598
  }
534
599
  };
535
600
  //#endregion
601
+ //#region src/message-stream/response-parser.ts
602
+ /** One wire format: a complete ■start … ■end envelope containing valid blocks. */
603
+ var ResponseParser = class {
604
+ _parser = new StreamingMessageParser();
605
+ _mode = "detect";
606
+ _discardPrefixLine = false;
607
+ _prefixDiagnostics = [];
608
+ _prefix = "";
609
+ _boundary = "";
610
+ _closed = false;
611
+ _finished = false;
612
+ _failure;
613
+ _trailer = "";
614
+ get framed() {
615
+ return this._mode === "framed";
616
+ }
617
+ get valid() {
618
+ return this._finished && this._closed && !this._failure;
619
+ }
620
+ get items() {
621
+ return this.valid ? this._parser.items : [];
622
+ }
623
+ get diagnostics() {
624
+ return [
625
+ ...this._prefixDiagnostics,
626
+ ...this._parser.diagnostics,
627
+ ...this._trailingDiagnostics,
628
+ ...this._failure ? [this._failure] : []
629
+ ];
630
+ }
631
+ push(chunk) {
632
+ if (this._finished) throw new Error("Response parser has already finished");
633
+ const events = [];
634
+ let forward = "";
635
+ const flush = () => {
636
+ if (forward) events.push(...this._parser.push(forward));
637
+ forward = "";
638
+ };
639
+ for (const char of chunk) {
640
+ if (this._mode === "detect") {
641
+ if (this._discardPrefixLine) {
642
+ if (char === "\n") this._discardPrefixLine = false;
643
+ continue;
644
+ }
645
+ if (!this._prefix && /\s/.test(char)) continue;
646
+ this._prefix += char;
647
+ const trimmed = this._prefix.trimEnd();
648
+ if (char === "\n" && trimmed === "\"\"\"") {
649
+ events.push(...this._parser.push(this._prefix));
650
+ this._prefix = "";
651
+ } else if (char === "\n" && trimmed === "■start") {
652
+ this._mode = "framed";
653
+ this._prefix = "";
654
+ } else if (!"■start".startsWith(this._prefix) && !/^■start[ \t\r]*$/.test(this._prefix) && !/^"{1,3}[ \t\r]*$/.test(this._prefix)) {
655
+ if (!this._prefixDiagnostics.length) {
656
+ const diagnostic = {
657
+ code: "unexpected-text",
658
+ message: "Discarded text before ■start"
659
+ };
660
+ this._prefixDiagnostics.push(diagnostic);
661
+ events.push({
662
+ type: "diagnostic",
663
+ diagnostic
664
+ });
665
+ }
666
+ this._prefix = "";
667
+ this._discardPrefixLine = char !== "\n";
668
+ }
669
+ continue;
670
+ }
671
+ if (this._closed) {
672
+ this._trailer += char;
673
+ continue;
674
+ }
675
+ if (this._boundary || char === "■") {
676
+ this._boundary += char;
677
+ if (this._boundary === "■end") {
678
+ flush();
679
+ events.push(...this._parser.finish());
680
+ this._boundary = "";
681
+ this._closed = true;
682
+ } else if (!"■end".startsWith(this._boundary)) {
683
+ forward += this._boundary;
684
+ this._boundary = "";
685
+ }
686
+ } else forward += char;
687
+ }
688
+ flush();
689
+ return events;
690
+ }
691
+ finish(stopReason) {
692
+ if (this._finished) return [];
693
+ this._finished = true;
694
+ const events = [];
695
+ if (this._mode === "detect") {
696
+ if (this._prefix.trim() === "■start") this._mode = "framed";
697
+ else this._fail("Missing ■start: every response must begin with the response envelope");
698
+ this._prefix = "";
699
+ }
700
+ if (this.framed) {
701
+ if (!this._boundary && stopReason === "stop") this._closed = true;
702
+ else if (this._boundary) events.push(...this._parser.push(this._boundary));
703
+ events.push(...this._parser.finish());
704
+ const trailer = this._trailer.trim();
705
+ if (!this._closed) this._fail("Missing ■end: the response envelope is incomplete");
706
+ else if (this._parser.diagnostics.some((d) => d.code !== "example-delimiter")) this._fail("The response envelope contains malformed protocol blocks");
707
+ if (!this._failure) this._validateBlocks();
708
+ if (trailer === "\"\"\"") {
709
+ const parser = new StreamingMessageParser();
710
+ events.push(...parser.push(trailer), ...parser.finish());
711
+ this._trailingDiagnostics = parser.diagnostics;
712
+ } else if (trailer) {
713
+ const diagnostic = {
714
+ code: "unexpected-text",
715
+ message: "Discarded content after ■end"
716
+ };
717
+ this._trailingDiagnostics.push(diagnostic);
718
+ events.push({
719
+ type: "diagnostic",
720
+ diagnostic
721
+ });
722
+ }
723
+ if (this._failure) events.push({
724
+ type: "diagnostic",
725
+ diagnostic: this._failure
726
+ });
727
+ } else if (this._failure) events.push({
728
+ type: "diagnostic",
729
+ diagnostic: this._failure
730
+ });
731
+ return events;
732
+ }
733
+ _trailingDiagnostics = [];
734
+ _validateBlocks() {
735
+ const items = this._parser.items;
736
+ const runs = items.filter((item) => item.kind === "run");
737
+ const next = items.findIndex((item) => item.kind === "next");
738
+ const run = items.findIndex((item) => item.kind === "run");
739
+ if (runs.length > 1 || run >= 0 && items.slice(run + 1).some((item) => item.kind === "send")) this._fail("Use at most one ■run, after all messages; never send a message after code");
740
+ else if (run >= 0 && hasTopLevelReturn(items[run].body ?? "")) {
741
+ if (run !== items.length - 1) this._fail("After code returning a result, write ■end and wait for the result");
742
+ } else if (next < 0 && run < 0) this._fail("Finish with ■next, or return a result from ■run for the next iteration");
743
+ }
744
+ _fail(message) {
745
+ this._failure = {
746
+ code: "invalid-envelope",
747
+ message
748
+ };
749
+ }
750
+ };
751
+ //#endregion
536
752
  //#region src/prompts/common.ts
537
753
  var common_exports = /* @__PURE__ */ __exportAll({
538
754
  parseAssistantResponse: () => parseAssistantResponse,
539
755
  replacePlaceholders: () => replacePlaceholders,
540
756
  toParsedAssistantResponse: () => toParsedAssistantResponse
541
757
  });
542
- /** Strips wrapping code fences the model may have added around the whole response. */
543
- const stripWrappingFences = (text) => text.trim().split("\n").filter((line, index, arr) => {
544
- if ((index === 0 || index === arr.length - 1) && line.trim().startsWith("```")) return false;
545
- return true;
546
- }).join("\n");
547
758
  /** Builds a {@link ParsedAssistantResponse} from parsed protocol items. */
548
759
  const toParsedAssistantResponse = (items, raw, diagnostics = []) => {
549
760
  var _run$body;
@@ -573,10 +784,10 @@ const toParsedAssistantResponse = (items, raw, diagnostics = []) => {
573
784
  } : void 0
574
785
  };
575
786
  };
576
- const parseAssistantResponse = (response) => {
577
- const parser = new StreamingMessageParser();
578
- parser.push(stripWrappingFences(response));
579
- parser.finish();
787
+ const parseAssistantResponse = (response, stopReason) => {
788
+ const parser = new ResponseParser();
789
+ parser.push(response);
790
+ parser.finish(stopReason);
580
791
  return toParsedAssistantResponse(parser.items, response, parser.diagnostics);
581
792
  };
582
793
  const replacePlaceholders = (prompt, values) => {
@@ -593,4 +804,4 @@ const replacePlaceholders = (prompt, values) => {
593
804
  return replaced.replace(/\n{3,}/g, "\n\n").trim();
594
805
  };
595
806
  //#endregion
596
- export { StreamingMessageParser as a, NAME_REGEX as c, toParsedAssistantResponse as i, parseAssistantResponse as n, tryParseJson as o, replacePlaceholders as r, MARKER as s, common_exports as t };
807
+ export { ResponseParser as a, MARKER as c, toParsedAssistantResponse as i, NAME_REGEX as l, parseAssistantResponse as n, StreamingMessageParser as o, replacePlaceholders as r, tryParseJson as s, common_exports as t };
@@ -1,10 +1,4 @@
1
1
  import { type Ctx } from '../ast.js';
2
2
  export declare const VariableTrackingFnIdentifier = "__var__";
3
- /**
4
- * Tracks user variables so the VM can read their values between iterations:
5
- * - after each variable declaration: `__var__("a", () => eval("a"));`
6
- * - at the top of function bodies, for their parameters
7
- *
8
- * The `eval` indirection captures the variable lazily in its own scope.
9
- */
3
+ /** Retain getters only for bindings visible between iterations, never local shadows. */
10
4
  export declare function applyVariableTracking(ctx: Ctx, variables: Set<string>): void;
@@ -349,77 +349,43 @@ function applyToolCallTracking(ctx, calls) {
349
349
  //#endregion
350
350
  //#region src/compiler/plugins/variable-extraction.ts
351
351
  const VariableTrackingFnIdentifier = "__var__";
352
- /**
353
- * Tracks user variables so the VM can read their values between iterations:
354
- * - after each variable declaration: `__var__("a", () => eval("a"));`
355
- * - at the top of function bodies, for their parameters
356
- *
357
- * The `eval` indirection captures the variable lazily in its own scope.
358
- */
352
+ const FUNCTION_TYPES$1 = /* @__PURE__ */ new Set([
353
+ "FunctionDeclaration",
354
+ "FunctionExpression",
355
+ "ArrowFunctionExpression"
356
+ ]);
357
+ function declaredNames(id) {
358
+ if (!id) return [];
359
+ if (id.type === "Identifier") return [id.name];
360
+ if (id.type === "RestElement") return declaredNames(id.argument);
361
+ if (id.type === "AssignmentPattern") return declaredNames(id.left);
362
+ if (id.type === "ArrayPattern") return id.elements.flatMap(declaredNames);
363
+ if (id.type === "ObjectPattern") return id.properties.flatMap((prop) => declaredNames(prop.type === "RestElement" ? prop.argument : prop.value));
364
+ return [];
365
+ }
366
+ /** Retain getters only for bindings visible between iterations, never local shadows. */
359
367
  function applyVariableTracking(ctx, variables) {
360
- const trackerFor = (name) => {
361
- if (name.startsWith("__")) return null;
362
- variables.add(name);
363
- return `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}));`;
364
- };
365
- const track = (names) => names.map(trackerFor).filter((t) => !!t).join("");
366
- const declaredNames = (id) => {
367
- if (id.type === "Identifier") return [id.name];
368
- if (id.type === "ObjectPattern") {
369
- const names = [];
370
- for (const prop of id.properties) {
371
- if (prop.type !== "Property") continue;
372
- if (prop.value.type === "Identifier") names.push(prop.value.name);
373
- else if (prop.value.type === "ObjectPattern") names.push(...declaredNames(prop.value));
374
- else if (prop.value.type === "AssignmentPattern" && prop.value.left.type === "Identifier") names.push(prop.value.left.name);
375
- }
376
- return names;
377
- }
378
- if (id.type === "ArrayPattern") {
379
- const names = [];
380
- for (const element of id.elements) {
381
- if (!element) continue;
382
- if (element.type === "Identifier") names.push(element.name);
383
- else if (element.type === "RestElement" && element.argument.type === "Identifier") names.push(element.argument.name);
384
- else if (element.type === "AssignmentPattern" && element.left.type === "Identifier") names.push(element.left.name);
385
- }
386
- return names;
387
- }
388
- return [];
389
- };
390
- const paramNames = (params) => {
391
- const names = [];
392
- for (const param of params) if (param.type === "Identifier") names.push(param.name);
393
- else if (param.type === "AssignmentPattern" && param.left.type === "Identifier") names.push(param.left.name);
394
- else if (param.type === "ObjectPattern") {
395
- for (const prop of param.properties) if (prop.type === "Property" && prop.value.type === "Identifier") names.push(prop.value.name);
396
- } else if (param.type === "ArrayPattern") {
397
- for (const element of param.elements) if ((element === null || element === void 0 ? void 0 : element.type) === "Identifier") names.push(element.name);
398
- }
399
- return names;
400
- };
401
- walk(ctx.ast, (node, parent) => {
402
- if (node.type === "VariableDeclaration") {
403
- if (parent && (parent.type === "ForStatement" || parent.type === "ForInStatement" || parent.type === "ForOfStatement")) return;
404
- const trackers = track(node.declarations.flatMap((d) => declaredNames(d.id)));
405
- if (trackers) {
406
- const semi = ctx.code[node.end - 1] === ";" ? "" : ";";
407
- ctx.ms.appendRight(node.end, `${semi}${trackers}`);
408
- }
409
- return;
410
- }
411
- if (node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression") {
412
- const trackers = track(paramNames(node.params));
413
- if (!trackers) return;
414
- const body = node.body;
415
- if (body.type === "BlockStatement") ctx.ms.appendRight(body.start + 1, trackers);
416
- else {
417
- const expressions = trackers.slice(0, -1).replaceAll(";", ",");
418
- ctx.ms.prependLeft(body.start, `(${expressions}, (`);
419
- ctx.ms.appendRight(body.end, "))");
420
- }
368
+ const wrapper = ctx.ast.body.find((node) => {
369
+ var _node$id;
370
+ return node.type === "FunctionDeclaration" && ((_node$id = node.id) === null || _node$id === void 0 ? void 0 : _node$id.name) === "__fn__";
371
+ });
372
+ const root = (wrapper === null || wrapper === void 0 ? void 0 : wrapper.body) ?? ctx.ast;
373
+ const varBindings = /* @__PURE__ */ new Set();
374
+ const track = (names) => names.map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}));`).join("");
375
+ walk(root, (node, parent, ancestors) => {
376
+ if (node.type !== "VariableDeclaration" || ancestors.some((ancestor) => FUNCTION_TYPES$1.has(ancestor.type) || ancestor.type === "StaticBlock")) return;
377
+ if (node.kind !== "var" && parent !== root) return;
378
+ const names = node.declarations.flatMap((declaration) => declaredNames(declaration.id)).filter((name) => !name.startsWith("__"));
379
+ for (const name of names) variables.add(name);
380
+ if (node.kind === "var" && parent !== root) for (const name of names) varBindings.add(name);
381
+ else if (node.declarations.length > 1) ctx.ms.appendLeft(node.start, track(names));
382
+ else {
383
+ const semi = ctx.code[node.end - 1] === ";" ? "" : ";";
384
+ ctx.ms.appendRight(node.end, semi + track(names));
421
385
  }
422
386
  });
387
+ const entry = root.body.find((node) => !node.directive);
388
+ if (entry && varBindings.size) ctx.ms.appendLeft(entry.start, track([...varBindings]));
423
389
  }
424
390
  //#endregion
425
391
  //#region src/compiler/compiler.ts
@@ -316,77 +316,43 @@ function applyToolCallTracking(ctx, calls) {
316
316
  //#endregion
317
317
  //#region src/compiler/plugins/variable-extraction.ts
318
318
  const VariableTrackingFnIdentifier = "__var__";
319
- /**
320
- * Tracks user variables so the VM can read their values between iterations:
321
- * - after each variable declaration: `__var__("a", () => eval("a"));`
322
- * - at the top of function bodies, for their parameters
323
- *
324
- * The `eval` indirection captures the variable lazily in its own scope.
325
- */
319
+ const FUNCTION_TYPES$1 = /* @__PURE__ */ new Set([
320
+ "FunctionDeclaration",
321
+ "FunctionExpression",
322
+ "ArrowFunctionExpression"
323
+ ]);
324
+ function declaredNames(id) {
325
+ if (!id) return [];
326
+ if (id.type === "Identifier") return [id.name];
327
+ if (id.type === "RestElement") return declaredNames(id.argument);
328
+ if (id.type === "AssignmentPattern") return declaredNames(id.left);
329
+ if (id.type === "ArrayPattern") return id.elements.flatMap(declaredNames);
330
+ if (id.type === "ObjectPattern") return id.properties.flatMap((prop) => declaredNames(prop.type === "RestElement" ? prop.argument : prop.value));
331
+ return [];
332
+ }
333
+ /** Retain getters only for bindings visible between iterations, never local shadows. */
326
334
  function applyVariableTracking(ctx, variables) {
327
- const trackerFor = (name) => {
328
- if (name.startsWith("__")) return null;
329
- variables.add(name);
330
- return `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}));`;
331
- };
332
- const track = (names) => names.map(trackerFor).filter((t) => !!t).join("");
333
- const declaredNames = (id) => {
334
- if (id.type === "Identifier") return [id.name];
335
- if (id.type === "ObjectPattern") {
336
- const names = [];
337
- for (const prop of id.properties) {
338
- if (prop.type !== "Property") continue;
339
- if (prop.value.type === "Identifier") names.push(prop.value.name);
340
- else if (prop.value.type === "ObjectPattern") names.push(...declaredNames(prop.value));
341
- else if (prop.value.type === "AssignmentPattern" && prop.value.left.type === "Identifier") names.push(prop.value.left.name);
342
- }
343
- return names;
344
- }
345
- if (id.type === "ArrayPattern") {
346
- const names = [];
347
- for (const element of id.elements) {
348
- if (!element) continue;
349
- if (element.type === "Identifier") names.push(element.name);
350
- else if (element.type === "RestElement" && element.argument.type === "Identifier") names.push(element.argument.name);
351
- else if (element.type === "AssignmentPattern" && element.left.type === "Identifier") names.push(element.left.name);
352
- }
353
- return names;
354
- }
355
- return [];
356
- };
357
- const paramNames = (params) => {
358
- const names = [];
359
- for (const param of params) if (param.type === "Identifier") names.push(param.name);
360
- else if (param.type === "AssignmentPattern" && param.left.type === "Identifier") names.push(param.left.name);
361
- else if (param.type === "ObjectPattern") {
362
- for (const prop of param.properties) if (prop.type === "Property" && prop.value.type === "Identifier") names.push(prop.value.name);
363
- } else if (param.type === "ArrayPattern") {
364
- for (const element of param.elements) if ((element === null || element === void 0 ? void 0 : element.type) === "Identifier") names.push(element.name);
365
- }
366
- return names;
367
- };
368
- walk(ctx.ast, (node, parent) => {
369
- if (node.type === "VariableDeclaration") {
370
- if (parent && (parent.type === "ForStatement" || parent.type === "ForInStatement" || parent.type === "ForOfStatement")) return;
371
- const trackers = track(node.declarations.flatMap((d) => declaredNames(d.id)));
372
- if (trackers) {
373
- const semi = ctx.code[node.end - 1] === ";" ? "" : ";";
374
- ctx.ms.appendRight(node.end, `${semi}${trackers}`);
375
- }
376
- return;
377
- }
378
- if (node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression") {
379
- const trackers = track(paramNames(node.params));
380
- if (!trackers) return;
381
- const body = node.body;
382
- if (body.type === "BlockStatement") ctx.ms.appendRight(body.start + 1, trackers);
383
- else {
384
- const expressions = trackers.slice(0, -1).replaceAll(";", ",");
385
- ctx.ms.prependLeft(body.start, `(${expressions}, (`);
386
- ctx.ms.appendRight(body.end, "))");
387
- }
335
+ const wrapper = ctx.ast.body.find((node) => {
336
+ var _node$id;
337
+ return node.type === "FunctionDeclaration" && ((_node$id = node.id) === null || _node$id === void 0 ? void 0 : _node$id.name) === "__fn__";
338
+ });
339
+ const root = (wrapper === null || wrapper === void 0 ? void 0 : wrapper.body) ?? ctx.ast;
340
+ const varBindings = /* @__PURE__ */ new Set();
341
+ const track = (names) => names.map((name) => `${VariableTrackingFnIdentifier}(${JSON.stringify(name)}, () => eval(${JSON.stringify(name)}));`).join("");
342
+ walk(root, (node, parent, ancestors) => {
343
+ if (node.type !== "VariableDeclaration" || ancestors.some((ancestor) => FUNCTION_TYPES$1.has(ancestor.type) || ancestor.type === "StaticBlock")) return;
344
+ if (node.kind !== "var" && parent !== root) return;
345
+ const names = node.declarations.flatMap((declaration) => declaredNames(declaration.id)).filter((name) => !name.startsWith("__"));
346
+ for (const name of names) variables.add(name);
347
+ if (node.kind === "var" && parent !== root) for (const name of names) varBindings.add(name);
348
+ else if (node.declarations.length > 1) ctx.ms.appendLeft(node.start, track(names));
349
+ else {
350
+ const semi = ctx.code[node.end - 1] === ";" ? "" : ";";
351
+ ctx.ms.appendRight(node.end, semi + track(names));
388
352
  }
389
353
  });
354
+ const entry = root.body.find((node) => !node.directive);
355
+ if (entry && varBindings.size) ctx.ms.appendLeft(entry.start, track([...varBindings]));
390
356
  }
391
357
  //#endregion
392
358
  //#region src/compiler/compiler.ts
@@ -1,5 +1,5 @@
1
- const require_compiler = require("./compiler-C-OI9sim.cjs");
2
- const require_jsx = require("./jsx-D5Y2cPo-.cjs");
1
+ const require_compiler = require("./compiler-BJJUmNS9.cjs");
2
+ const require_jsx = require("./jsx-BJ6GWXI2.cjs");
3
3
  //#region src/component.ts
4
4
  var component_exports = /* @__PURE__ */ require_compiler.__exportAll({
5
5
  Component: () => Component,
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.js";
2
- import { n as isAnyJsxComponent, r as isJsxComponent, t as createJsxComponent } from "./jsx-B0iYyvfr.js";
2
+ import { n as isAnyJsxComponent, r as isJsxComponent, t as createJsxComponent } from "./jsx-CIgdGGVs.js";
3
3
  //#region src/component.ts
4
4
  var component_exports = /* @__PURE__ */ __exportAll({
5
5
  Component: () => Component,