@mindstudio-ai/local-model-tunnel 0.5.40 → 0.5.42

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.
@@ -7,7 +7,7 @@ import {
7
7
  setProviderInstallPath,
8
8
  submitProgress,
9
9
  submitResult
10
- } from "./chunk-I3WNZIXI.js";
10
+ } from "./chunk-6LWKL7BC.js";
11
11
 
12
12
  // src/providers/ollama/index.ts
13
13
  import { Ollama } from "ollama";
@@ -1395,4 +1395,4 @@ export {
1395
1395
  requestEvents,
1396
1396
  TunnelRunner
1397
1397
  };
1398
- //# sourceMappingURL=chunk-55CLKSH5.js.map
1398
+ //# sourceMappingURL=chunk-2ND2YJQR.js.map
@@ -421,6 +421,45 @@ function logScenarioExecution(entry) {
421
421
  stats: entry.result?.stats ?? null
422
422
  });
423
423
  }
424
+ function logMethodStart(requestId, sessionId, method, input) {
425
+ ndjsonLog.append({
426
+ ts: Date.now(),
427
+ level: "info",
428
+ module: "execution",
429
+ msg: "Method started",
430
+ type: "method-start",
431
+ requestId,
432
+ sessionId,
433
+ method,
434
+ input
435
+ });
436
+ }
437
+ function logMethodStdout(requestId, sessionId, method, lines) {
438
+ ndjsonLog.append({
439
+ ts: Date.now(),
440
+ level: "info",
441
+ module: "execution",
442
+ msg: "Method stdout",
443
+ type: "method-stdout",
444
+ requestId,
445
+ sessionId,
446
+ method,
447
+ stdout: lines
448
+ });
449
+ }
450
+ function logBackgroundStdout(requestId, sessionId, method, lines) {
451
+ ndjsonLog.append({
452
+ ts: Date.now(),
453
+ level: "info",
454
+ module: "execution",
455
+ msg: "Background stdout",
456
+ type: "method-background-stdout",
457
+ requestId,
458
+ sessionId,
459
+ method,
460
+ stdout: lines
461
+ });
462
+ }
424
463
  function closeRequestLog() {
425
464
  ndjsonLog.close();
426
465
  }
@@ -582,6 +621,7 @@ function findNearestNodeModules(startDir) {
582
621
  // src/dev/execution/executor.ts
583
622
  import { fork } from "child_process";
584
623
  import { writeFile, unlink as unlink2 } from "fs/promises";
624
+ import { readFileSync } from "fs";
585
625
  import { join as join4 } from "path";
586
626
  import { tmpdir } from "os";
587
627
  import { randomBytes } from "crypto";
@@ -589,9 +629,10 @@ var EXECUTION_TIMEOUT_MS = 30 * 60 * 1e3;
589
629
  var worker = null;
590
630
  var workerScriptPath = null;
591
631
  var workerProjectRoot = null;
632
+ var workerSupportsAls = false;
592
633
  var pending = /* @__PURE__ */ new Map();
593
- function buildWorkerScript() {
594
- return `
634
+ var requestMeta = /* @__PURE__ */ new Map();
635
+ var SERIALIZE_ERROR_FN = `
595
636
  function serializeError(err) {
596
637
  if (!err) return { message: 'Unknown error' };
597
638
 
@@ -626,6 +667,117 @@ function serializeError(err) {
626
667
 
627
668
  return serialized;
628
669
  }
670
+ `;
671
+ function buildAlsWorkerScript() {
672
+ return `
673
+ import { AsyncLocalStorage } from 'node:async_hooks';
674
+ import { format } from 'node:util';
675
+ import { runWithContext } from '@mindstudio-ai/agent';
676
+
677
+ ${SERIALIZE_ERROR_FN}
678
+
679
+ // Per-request console capture via AsyncLocalStorage
680
+ const consoleAls = new AsyncLocalStorage();
681
+ const _origLog = console.log;
682
+ const _origWarn = console.warn;
683
+ const _origError = console.error;
684
+
685
+ console.log = (...args) => {
686
+ const stdout = consoleAls.getStore();
687
+ if (stdout) stdout.push(format(...args));
688
+ _origLog(...args);
689
+ };
690
+ console.warn = (...args) => {
691
+ const stdout = consoleAls.getStore();
692
+ if (stdout) stdout.push(format(...args));
693
+ _origWarn(...args);
694
+ };
695
+ console.error = (...args) => {
696
+ const stdout = consoleAls.getStore();
697
+ if (stdout) stdout.push(format(...args));
698
+ _origError(...args);
699
+ };
700
+
701
+ process.on('message', async (msg) => {
702
+ const { id, transpiledPath, methodExport, input, auth, databases, authorizationToken, apiBaseUrl, streamId } = msg;
703
+
704
+ const ctx = {
705
+ callbackToken: authorizationToken,
706
+ remoteHostname: apiBaseUrl,
707
+ auth: auth ?? { userId: null, roleAssignments: [] },
708
+ databases: databases ?? [],
709
+ streamId: streamId ?? undefined,
710
+ };
711
+
712
+ const stdout = [];
713
+ let flushed = 0;
714
+ let done = false;
715
+
716
+ // Flush new stdout lines every 1s while the method is running.
717
+ // After the method returns, switches to background-stdout type.
718
+ const flushInterval = setInterval(() => {
719
+ if (stdout.length > flushed) {
720
+ const lines = stdout.slice(flushed);
721
+ flushed = stdout.length;
722
+ try {
723
+ process.send({ type: done ? 'background-stdout' : 'stdout', id, lines });
724
+ } catch {}
725
+ idleTicks = 0;
726
+ } else if (done) {
727
+ idleTicks++;
728
+ if (idleTicks >= 2) {
729
+ clearInterval(flushInterval);
730
+ try { process.send({ type: 'stdout-end', id }); } catch {}
731
+ }
732
+ }
733
+ }, 1000);
734
+ let idleTicks = 0;
735
+
736
+ process.send({ type: 'start', id });
737
+
738
+ const startTime = Date.now();
739
+
740
+ try {
741
+ const returnValue = await consoleAls.run(stdout, () =>
742
+ runWithContext(ctx, async () => {
743
+ const mod = await import(transpiledPath + '?t=' + Date.now());
744
+ const fn = mod[methodExport];
745
+ if (typeof fn !== 'function') {
746
+ throw new Error(methodExport + ' is not a function (got ' + typeof fn + ')');
747
+ }
748
+ return fn(input);
749
+ }),
750
+ );
751
+ const stats = { memoryUsedBytes: process.memoryUsage().heapUsed, executionTimeMs: Date.now() - startTime };
752
+
753
+ // Final flush of any remaining lines before sending result
754
+ if (stdout.length > flushed) {
755
+ try { process.send({ type: 'stdout', id, lines: stdout.slice(flushed) }); } catch {}
756
+ flushed = stdout.length;
757
+ }
758
+
759
+ done = true;
760
+ process.send({ id, success: true, output: returnValue, stats });
761
+ } catch (err) {
762
+ const stats = { memoryUsedBytes: process.memoryUsage().heapUsed, executionTimeMs: Date.now() - startTime };
763
+
764
+ if (stdout.length > flushed) {
765
+ try { process.send({ type: 'stdout', id, lines: stdout.slice(flushed) }); } catch {}
766
+ flushed = stdout.length;
767
+ }
768
+
769
+ done = true;
770
+ process.send({ id, success: false, error: serializeError(err), stats });
771
+ }
772
+ });
773
+
774
+ // Signal ready
775
+ process.send({ type: 'ready' });
776
+ `;
777
+ }
778
+ function buildLegacyWorkerScript() {
779
+ return `
780
+ ${SERIALIZE_ERROR_FN}
629
781
 
630
782
  // Save original console methods so we can restore after each request
631
783
  const _origLog = console.log;
@@ -677,6 +829,17 @@ process.on('message', async (msg) => {
677
829
  process.send({ type: 'ready' });
678
830
  `;
679
831
  }
832
+ function detectAlsSupport(projectRoot) {
833
+ try {
834
+ const pkgPath = join4(projectRoot, "node_modules", "@mindstudio-ai", "agent", "package.json");
835
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
836
+ const parts = (pkg.version || "").split(".").map(Number);
837
+ const [major = 0, minor = 0, patch = 0] = parts;
838
+ return major > 0 || minor > 1 || minor === 1 && patch >= 46;
839
+ } catch {
840
+ return false;
841
+ }
842
+ }
680
843
  async function ensureWorker(projectRoot) {
681
844
  if (worker?.connected && workerProjectRoot === projectRoot) {
682
845
  return worker;
@@ -695,14 +858,17 @@ async function ensureWorker(projectRoot) {
695
858
  });
696
859
  workerScriptPath = null;
697
860
  }
861
+ workerSupportsAls = detectAlsSupport(projectRoot);
862
+ log.info("executor", "SDK context support", { als: workerSupportsAls });
698
863
  const scriptPath = join4(
699
864
  tmpdir(),
700
865
  `ms-dev-worker-${randomBytes(4).toString("hex")}.mjs`
701
866
  );
702
- await writeFile(scriptPath, buildWorkerScript(), "utf-8");
867
+ const script = workerSupportsAls ? buildAlsWorkerScript() : buildLegacyWorkerScript();
868
+ await writeFile(scriptPath, script, "utf-8");
703
869
  workerScriptPath = scriptPath;
704
870
  workerProjectRoot = projectRoot;
705
- log.debug("executor", "Spawning method execution process", { cwd: projectRoot, scriptPath });
871
+ log.debug("executor", "Spawning method execution process", { cwd: projectRoot, scriptPath, als: workerSupportsAls });
706
872
  const child = fork(scriptPath, [], {
707
873
  cwd: projectRoot,
708
874
  stdio: ["ignore", "pipe", "pipe", "ipc"],
@@ -721,6 +887,21 @@ async function ensureWorker(projectRoot) {
721
887
  });
722
888
  child.on("message", (msg) => {
723
889
  if (!msg?.id) return;
890
+ const meta = requestMeta.get(msg.id);
891
+ switch (msg.type) {
892
+ case "start":
893
+ if (meta) logMethodStart(msg.id, meta.sessionId, meta.method, meta.input);
894
+ return;
895
+ case "stdout":
896
+ if (meta && msg.lines?.length) logMethodStdout(msg.id, meta.sessionId, meta.method, msg.lines);
897
+ return;
898
+ case "background-stdout":
899
+ if (meta && msg.lines?.length) logBackgroundStdout(msg.id, meta.sessionId, meta.method, msg.lines);
900
+ return;
901
+ case "stdout-end":
902
+ requestMeta.delete(msg.id);
903
+ return;
904
+ }
724
905
  const req = pending.get(msg.id);
725
906
  if (!req) return;
726
907
  pending.delete(msg.id);
@@ -752,6 +933,9 @@ function enqueue(fn) {
752
933
  return task;
753
934
  }
754
935
  function executeMethod(opts) {
936
+ if (workerSupportsAls) {
937
+ return executeMethodInWorker(opts);
938
+ }
755
939
  return enqueue(() => executeMethodInWorker(opts));
756
940
  }
757
941
  async function executeMethodInWorker(opts) {
@@ -768,6 +952,9 @@ async function executeMethodInWorker(opts) {
768
952
  });
769
953
  }, EXECUTION_TIMEOUT_MS);
770
954
  pending.set(id, { resolve: resolve2, timer });
955
+ if (opts.sessionId) {
956
+ requestMeta.set(id, { sessionId: opts.sessionId, method: opts.methodExport, input: opts.input });
957
+ }
771
958
  w.send({
772
959
  id,
773
960
  transpiledPath: opts.transpiledPath,
@@ -793,10 +980,12 @@ async function cleanupWorker() {
793
980
  workerScriptPath = null;
794
981
  }
795
982
  workerProjectRoot = null;
983
+ workerSupportsAls = false;
796
984
  for (const [, req] of pending) {
797
985
  clearTimeout(req.timer);
798
986
  }
799
987
  pending.clear();
988
+ requestMeta.clear();
800
989
  queueTail = Promise.resolve();
801
990
  }
802
991
 
@@ -988,7 +1177,7 @@ function formatErrorForDisplay(error) {
988
1177
  }
989
1178
 
990
1179
  // src/dev/execution/agent-config.ts
991
- import { readFileSync } from "fs";
1180
+ import { readFileSync as readFileSync2 } from "fs";
992
1181
  import { join as join5, dirname as dirname2 } from "path";
993
1182
  function readAgentConfig(projectRoot, appConfig) {
994
1183
  const agentInterface = appConfig.interfaces.find(
@@ -1000,7 +1189,7 @@ function readAgentConfig(projectRoot, appConfig) {
1000
1189
  const configPath = join5(projectRoot, agentInterface.path);
1001
1190
  let raw;
1002
1191
  try {
1003
- raw = readFileSync(configPath, "utf-8");
1192
+ raw = readFileSync2(configPath, "utf-8");
1004
1193
  } catch {
1005
1194
  throw new Error(
1006
1195
  `Agent config not found at ${agentInterface.path} \u2014 run your build command`
@@ -1012,7 +1201,7 @@ function readAgentConfig(projectRoot, appConfig) {
1012
1201
  const systemPromptPath = join5(agentDir, config2.systemPrompt);
1013
1202
  let systemPrompt;
1014
1203
  try {
1015
- systemPrompt = readFileSync(systemPromptPath, "utf-8");
1204
+ systemPrompt = readFileSync2(systemPromptPath, "utf-8");
1016
1205
  } catch {
1017
1206
  throw new Error(
1018
1207
  `Agent system prompt not found at ${config2.systemPrompt} \u2014 run your build command`
@@ -1023,7 +1212,7 @@ function readAgentConfig(projectRoot, appConfig) {
1023
1212
  const descPath = join5(agentDir, tool.description);
1024
1213
  let description;
1025
1214
  try {
1026
- description = readFileSync(descPath, "utf-8");
1215
+ description = readFileSync2(descPath, "utf-8");
1027
1216
  } catch {
1028
1217
  throw new Error(
1029
1218
  `Agent tool description not found at ${tool.description} for method "${tool.method}" \u2014 run your build command`
@@ -1168,7 +1357,8 @@ var DevRunner = class {
1168
1357
  databases: this.session.databases,
1169
1358
  authorizationToken,
1170
1359
  apiBaseUrl: getApiBaseUrl(),
1171
- projectRoot: this.projectRoot
1360
+ projectRoot: this.projectRoot,
1361
+ sessionId: this.session.sessionId
1172
1362
  });
1173
1363
  const duration = Date.now() - startTime;
1174
1364
  if (result.success) {
@@ -1246,7 +1436,8 @@ var DevRunner = class {
1246
1436
  databases: this.session.databases,
1247
1437
  authorizationToken,
1248
1438
  apiBaseUrl: getApiBaseUrl(),
1249
- projectRoot: this.projectRoot
1439
+ projectRoot: this.projectRoot,
1440
+ sessionId: this.session.sessionId
1250
1441
  });
1251
1442
  if (!result.success) {
1252
1443
  const error = result.error?.message ?? "Scenario seed failed";
@@ -1387,6 +1578,7 @@ var DevRunner = class {
1387
1578
  authorizationToken: request.authorizationToken,
1388
1579
  apiBaseUrl: getApiBaseUrl(),
1389
1580
  projectRoot: this.projectRoot,
1581
+ sessionId: this.session.sessionId,
1390
1582
  streamId: request.streamId
1391
1583
  });
1392
1584
  const t2 = Date.now();
@@ -2566,6 +2758,8 @@ var DevProxy = class _DevProxy {
2566
2758
  async resolveAuthCookie(cookie) {
2567
2759
  const apiBaseUrl = getApiBaseUrl();
2568
2760
  const url = new URL(`/_internal/v2/apps/${this.appId}/auth/me`, apiBaseUrl);
2761
+ const releaseId = this.clientContext.releaseId;
2762
+ if (releaseId) url.searchParams.set("releaseId", releaseId);
2569
2763
  const isHttps = url.protocol === "https:";
2570
2764
  const httpModule = isHttps ? https : http;
2571
2765
  return new Promise((resolve2) => {
@@ -2573,7 +2767,7 @@ var DevProxy = class _DevProxy {
2573
2767
  {
2574
2768
  hostname: url.hostname,
2575
2769
  port: url.port || (isHttps ? 443 : 80),
2576
- path: url.pathname,
2770
+ path: url.pathname + url.search,
2577
2771
  method: "GET",
2578
2772
  headers: {
2579
2773
  cookie: `__ms_auth=${cookie}`,
@@ -2667,13 +2861,13 @@ ${agentScript}`;
2667
2861
  };
2668
2862
 
2669
2863
  // src/dev/config/app-config.ts
2670
- import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
2864
+ import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
2671
2865
  import { join as join6, dirname as dirname3 } from "path";
2672
2866
  function detectAppConfig(cwd = process.cwd()) {
2673
2867
  const appJsonPath = join6(cwd, "mindstudio.json");
2674
2868
  if (!existsSync2(appJsonPath)) return null;
2675
2869
  try {
2676
- const raw = readFileSync2(appJsonPath, "utf-8");
2870
+ const raw = readFileSync3(appJsonPath, "utf-8");
2677
2871
  const parsed = JSON.parse(raw);
2678
2872
  if (!parsed.name || !Array.isArray(parsed.methods)) {
2679
2873
  return null;
@@ -2715,7 +2909,7 @@ function getWebInterfaceConfig(appConfig, cwd = process.cwd()) {
2715
2909
  return null;
2716
2910
  }
2717
2911
  try {
2718
- const raw = readFileSync2(configPath, "utf-8");
2912
+ const raw = readFileSync3(configPath, "utf-8");
2719
2913
  const parsed = JSON.parse(raw);
2720
2914
  const web = parsed.web;
2721
2915
  if (!web || typeof web !== "object") {
@@ -2747,7 +2941,7 @@ function readTableSources(appConfig, cwd = process.cwd()) {
2747
2941
  continue;
2748
2942
  }
2749
2943
  try {
2750
- const source = readFileSync2(filePath, "utf-8");
2944
+ const source = readFileSync3(filePath, "utf-8");
2751
2945
  const name = table.export;
2752
2946
  results.push({ name, source });
2753
2947
  } catch (err) {
@@ -2885,6 +3079,8 @@ export {
2885
3079
  getUploadUrl,
2886
3080
  createAuthSession,
2887
3081
  devRequestEvents,
3082
+ initRequestLog,
3083
+ closeRequestLog,
2888
3084
  pollForRequest,
2889
3085
  submitProgress,
2890
3086
  submitResult,
@@ -2895,8 +3091,6 @@ export {
2895
3091
  pollDeviceAuth,
2896
3092
  getEditorSessions,
2897
3093
  disconnectHeartbeat,
2898
- initRequestLog,
2899
- closeRequestLog,
2900
3094
  DevRunner,
2901
3095
  initBrowserLog,
2902
3096
  closeBrowserLog,
@@ -2911,4 +3105,4 @@ export {
2911
3105
  watchTableFiles,
2912
3106
  watchConfigFile
2913
3107
  };
2914
- //# sourceMappingURL=chunk-I3WNZIXI.js.map
3108
+ //# sourceMappingURL=chunk-6LWKL7BC.js.map