@mindstudio-ai/local-model-tunnel 0.5.41 → 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.
- package/dist/{chunk-DKTUVHTX.js → chunk-2ND2YJQR.js} +2 -2
- package/dist/{chunk-VO5KLV5S.js → chunk-6LWKL7BC.js} +209 -17
- package/dist/chunk-6LWKL7BC.js.map +1 -0
- package/dist/{chunk-3GMBQERL.js → chunk-RXFQETVJ.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/headless.js +2 -2
- package/dist/index.js +3 -3
- package/dist/{tui-K5LIL42S.js → tui-AN4UCPZK.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-VO5KLV5S.js.map +0 -1
- /package/dist/{chunk-DKTUVHTX.js.map → chunk-2ND2YJQR.js.map} +0 -0
- /package/dist/{chunk-3GMBQERL.js.map → chunk-RXFQETVJ.js.map} +0 -0
- /package/dist/{tui-K5LIL42S.js.map → tui-AN4UCPZK.js.map} +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
setProviderInstallPath,
|
|
8
8
|
submitProgress,
|
|
9
9
|
submitResult
|
|
10
|
-
} from "./chunk-
|
|
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-
|
|
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
|
-
|
|
594
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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();
|
|
@@ -2669,13 +2861,13 @@ ${agentScript}`;
|
|
|
2669
2861
|
};
|
|
2670
2862
|
|
|
2671
2863
|
// src/dev/config/app-config.ts
|
|
2672
|
-
import { readFileSync as
|
|
2864
|
+
import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
|
|
2673
2865
|
import { join as join6, dirname as dirname3 } from "path";
|
|
2674
2866
|
function detectAppConfig(cwd = process.cwd()) {
|
|
2675
2867
|
const appJsonPath = join6(cwd, "mindstudio.json");
|
|
2676
2868
|
if (!existsSync2(appJsonPath)) return null;
|
|
2677
2869
|
try {
|
|
2678
|
-
const raw =
|
|
2870
|
+
const raw = readFileSync3(appJsonPath, "utf-8");
|
|
2679
2871
|
const parsed = JSON.parse(raw);
|
|
2680
2872
|
if (!parsed.name || !Array.isArray(parsed.methods)) {
|
|
2681
2873
|
return null;
|
|
@@ -2717,7 +2909,7 @@ function getWebInterfaceConfig(appConfig, cwd = process.cwd()) {
|
|
|
2717
2909
|
return null;
|
|
2718
2910
|
}
|
|
2719
2911
|
try {
|
|
2720
|
-
const raw =
|
|
2912
|
+
const raw = readFileSync3(configPath, "utf-8");
|
|
2721
2913
|
const parsed = JSON.parse(raw);
|
|
2722
2914
|
const web = parsed.web;
|
|
2723
2915
|
if (!web || typeof web !== "object") {
|
|
@@ -2749,7 +2941,7 @@ function readTableSources(appConfig, cwd = process.cwd()) {
|
|
|
2749
2941
|
continue;
|
|
2750
2942
|
}
|
|
2751
2943
|
try {
|
|
2752
|
-
const source =
|
|
2944
|
+
const source = readFileSync3(filePath, "utf-8");
|
|
2753
2945
|
const name = table.export;
|
|
2754
2946
|
results.push({ name, source });
|
|
2755
2947
|
} catch (err) {
|
|
@@ -2887,6 +3079,8 @@ export {
|
|
|
2887
3079
|
getUploadUrl,
|
|
2888
3080
|
createAuthSession,
|
|
2889
3081
|
devRequestEvents,
|
|
3082
|
+
initRequestLog,
|
|
3083
|
+
closeRequestLog,
|
|
2890
3084
|
pollForRequest,
|
|
2891
3085
|
submitProgress,
|
|
2892
3086
|
submitResult,
|
|
@@ -2897,8 +3091,6 @@ export {
|
|
|
2897
3091
|
pollDeviceAuth,
|
|
2898
3092
|
getEditorSessions,
|
|
2899
3093
|
disconnectHeartbeat,
|
|
2900
|
-
initRequestLog,
|
|
2901
|
-
closeRequestLog,
|
|
2902
3094
|
DevRunner,
|
|
2903
3095
|
initBrowserLog,
|
|
2904
3096
|
closeBrowserLog,
|
|
@@ -2913,4 +3105,4 @@ export {
|
|
|
2913
3105
|
watchTableFiles,
|
|
2914
3106
|
watchConfigFile
|
|
2915
3107
|
};
|
|
2916
|
-
//# sourceMappingURL=chunk-
|
|
3108
|
+
//# sourceMappingURL=chunk-6LWKL7BC.js.map
|