@ax-llm/ax 17.0.0 → 17.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.
package/index.cjs CHANGED
@@ -661,6 +661,54 @@ if (_isNodeWorker) {
661
661
  const _scope = typeof self !== 'undefined' ? self : globalThis;
662
662
  const _AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
663
663
  const _FUNCTION_REF_KEY = '${Ql}';
664
+ const _LAST_LINE_NON_EXPRESSION_START =
665
+ /^(if|for|while|switch|try|catch|finally|function|class|import|export|throw|return|var|let|const|break|continue|debugger)\\b/;
666
+ const _TOP_LEVEL_RETURN_ONLY = /^\\s*return\\s+([^\\n;]+?)\\s*;?\\s*$/;
667
+ const _injectAsyncAutoReturn = (code) => {
668
+ const lines = code.split('\\n');
669
+ let tail = lines.length - 1;
670
+ while (tail >= 0 && !lines[tail].trim()) {
671
+ tail -= 1;
672
+ }
673
+ if (tail < 0) {
674
+ return code;
675
+ }
676
+
677
+ let head = lines.slice(0, tail).join('\\n');
678
+ const rawLastLine = lines[tail].trim();
679
+ let lastLine = rawLastLine.replace(/;\\s*$/, '');
680
+ const lastSemi = lastLine.lastIndexOf(';');
681
+ if (lastSemi !== -1) {
682
+ const maybeExpression = lastLine.slice(lastSemi + 1).trim();
683
+ const prefixStatement = lastLine.slice(0, lastSemi).trim();
684
+ if (maybeExpression) {
685
+ if (prefixStatement) {
686
+ head = head ? \`\${head}\\n\${prefixStatement};\` : \`\${prefixStatement};\`;
687
+ }
688
+ lastLine = maybeExpression;
689
+ }
690
+ }
691
+
692
+ if (!lastLine) {
693
+ return code;
694
+ }
695
+ if (_LAST_LINE_NON_EXPRESSION_START.test(lastLine)) {
696
+ return code;
697
+ }
698
+ if (lastLine === '}' || lastLine === '};') {
699
+ return code;
700
+ }
701
+
702
+ return head ? \`\${head}\\nreturn (\${lastLine});\` : \`return (\${lastLine});\`;
703
+ };
704
+ const _rewriteTopLevelReturnForSyncEval = (code) => {
705
+ const match = _TOP_LEVEL_RETURN_ONLY.exec(code);
706
+ if (!match) {
707
+ return code;
708
+ }
709
+ const expression = (match[1] || '').trim();
710
+ return expression || code;
711
+ };
664
712
  const _send = (msg) => {
665
713
  if (_nodeParentPort) {
666
714
  _nodeParentPort.postMessage(msg);
@@ -796,12 +844,20 @@ _setOnMessage(async (e) => {
796
844
  if (/\\bawait\\b/.test(code)) {
797
845
  // Async path: compile as async function so top-level await/return work.
798
846
  // Bare assignments persist via global object in non-strict function code.
799
- const fn = new _AsyncFunction(code);
847
+ // Also auto-return a simple trailing expression when no explicit return.
848
+ let asyncCode = code;
849
+ try {
850
+ asyncCode = _injectAsyncAutoReturn(code);
851
+ } catch (_e) {
852
+ asyncCode = code;
853
+ }
854
+ const fn = new _AsyncFunction(asyncCode);
800
855
  result = await fn();
801
856
  } else {
802
857
  // Sync path: indirect eval runs in worker global scope.
803
858
  // var declarations persist on self.
804
- result = (0, eval)(code);
859
+ const syncCode = _rewriteTopLevelReturnForSyncEval(code);
860
+ result = (0, eval)(syncCode);
805
861
  }
806
862
  try {
807
863
  _send({ type: 'result', id, value: result });
@@ -849,7 +905,8 @@ There is also a hard runtime cap on context size per \`llmQuery\` call. If you h
849
905
 
850
906
  ### Execution rules
851
907
  - Sync code: use \`var\` (not \`const\`/\`let\`) to persist variables across calls. The last expression is auto-returned.
852
- - Async code (with \`await\`): use bare assignments (e.g. \`results = await ...\`) to persist. Use \`return\` to produce output.
908
+ - Async code (with \`await\`): use bare assignments (e.g. \`results = await ...\`) to persist. A simple trailing expression is also auto-returned, but explicit \`return\` is still the safest option.
909
+ - Convenience: \`return <expr>\` also works as a single-line sync snippet.
853
910
 
854
911
  ### Example
855
912
  Analyzing \`${o}\`: