meshy-node 0.4.5 → 0.4.6
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 +1 -1
- package/dashboard/assets/DashboardPage-D90kD6BP.js +124 -0
- package/dashboard/assets/{DashboardShared-BdpxWcCV.js → DashboardShared-C3JGW4Hk.js} +2 -2
- package/dashboard/assets/{DiffTab-CMaYxRh2.js → DiffTab-Dwqf5Gav.js} +2 -2
- package/dashboard/assets/{FilesTab-8EoW1a5F.js → FilesTab-DGtXQ9rR.js} +1 -1
- package/dashboard/assets/{PreviewTab-DJEeyGWo.js → PreviewTab-BcdMUFw3.js} +2 -2
- package/dashboard/assets/{SharedConversationPage-hyt9OBkY.js → SharedConversationPage-CYx3AV6M.js} +3 -3
- package/dashboard/assets/{file-BBYxpzot.js → file-BeUioHu4.js} +1 -1
- package/dashboard/assets/{folder-BCnKXNII.js → folder-Dl50jm8B.js} +1 -1
- package/dashboard/assets/index-BOC8nP24.css +1 -0
- package/dashboard/assets/index-D2UnB_kx.js +301 -0
- package/dashboard/assets/play-B08sSxiw.js +6 -0
- package/dashboard/index.html +2 -2
- package/main.cjs +239 -44
- package/package.json +1 -1
- package/runtime-metadata.json +5 -5
- package/dashboard/assets/DashboardPage-ByMFp2Hx.js +0 -124
- package/dashboard/assets/index-BgSOSh2K.js +0 -301
- package/dashboard/assets/index-BzzXPy7Y.css +0 -1
- package/dashboard/assets/input-BcMrrsRJ.js +0 -6
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as a}from"./index-D2UnB_kx.js";/**
|
|
2
|
+
* @license lucide-react v1.7.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const o=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],e=a("play",o);export{e as P};
|
package/dashboard/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Meshy Dashboard</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🕸</text></svg>" />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-D2UnB_kx.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BOC8nP24.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
package/main.cjs
CHANGED
|
@@ -33863,6 +33863,49 @@ var LeaderElection = class {
|
|
|
33863
33863
|
var import_node_crypto5 = require("crypto");
|
|
33864
33864
|
var fs4 = __toESM(require("fs"), 1);
|
|
33865
33865
|
var path4 = __toESM(require("path"), 1);
|
|
33866
|
+
|
|
33867
|
+
// ../../packages/core/src/tasks/task-join-snapshot.ts
|
|
33868
|
+
var JOIN_TASK_SNAPSHOT_PAYLOAD_KEY = "__meshyJoinSnapshot";
|
|
33869
|
+
var MAX_JOIN_TASK_ERROR_LENGTH = 2e3;
|
|
33870
|
+
function truncate(value, maxLength) {
|
|
33871
|
+
if (value === null || value.length <= maxLength) {
|
|
33872
|
+
return value;
|
|
33873
|
+
}
|
|
33874
|
+
return `${value.slice(0, maxLength)}...`;
|
|
33875
|
+
}
|
|
33876
|
+
function shouldIncludeTaskInJoinSnapshot(task, selfId) {
|
|
33877
|
+
return task.assignedTo === null || task.assignedTo === selfId;
|
|
33878
|
+
}
|
|
33879
|
+
function createJoinTaskSnapshot(task, ownerNodeId) {
|
|
33880
|
+
return {
|
|
33881
|
+
...task,
|
|
33882
|
+
description: "",
|
|
33883
|
+
payload: {
|
|
33884
|
+
[JOIN_TASK_SNAPSHOT_PAYLOAD_KEY]: {
|
|
33885
|
+
ownerNodeId,
|
|
33886
|
+
version: 1
|
|
33887
|
+
}
|
|
33888
|
+
},
|
|
33889
|
+
result: null,
|
|
33890
|
+
error: truncate(task.error, MAX_JOIN_TASK_ERROR_LENGTH)
|
|
33891
|
+
};
|
|
33892
|
+
}
|
|
33893
|
+
function buildJoinTaskSnapshots(tasks, ownerNodeId) {
|
|
33894
|
+
return tasks.filter((task) => shouldIncludeTaskInJoinSnapshot(task, ownerNodeId)).map((task) => createJoinTaskSnapshot(task, ownerNodeId));
|
|
33895
|
+
}
|
|
33896
|
+
function getJoinTaskSnapshotOwnerId(task) {
|
|
33897
|
+
const metadata = task.payload[JOIN_TASK_SNAPSHOT_PAYLOAD_KEY];
|
|
33898
|
+
if (typeof metadata !== "object" || metadata === null) {
|
|
33899
|
+
return null;
|
|
33900
|
+
}
|
|
33901
|
+
const ownerNodeId = metadata.ownerNodeId;
|
|
33902
|
+
return typeof ownerNodeId === "string" && ownerNodeId.length > 0 ? ownerNodeId : null;
|
|
33903
|
+
}
|
|
33904
|
+
function isJoinTaskSnapshot(task) {
|
|
33905
|
+
return getJoinTaskSnapshotOwnerId(task) !== null;
|
|
33906
|
+
}
|
|
33907
|
+
|
|
33908
|
+
// ../../packages/core/src/tasks/task-engine.ts
|
|
33866
33909
|
function nodeSupportsAgent(node, agent) {
|
|
33867
33910
|
return !node.supportedAgents || node.supportedAgents.length === 0 || node.supportedAgents.includes(agent);
|
|
33868
33911
|
}
|
|
@@ -34148,7 +34191,9 @@ var TaskEngine = class {
|
|
|
34148
34191
|
if (now - task.updatedAt < backoff) continue;
|
|
34149
34192
|
}
|
|
34150
34193
|
const previousNodeId = this.previousAssignments.get(task.id);
|
|
34151
|
-
const
|
|
34194
|
+
const snapshotOwnerId = getJoinTaskSnapshotOwnerId(task);
|
|
34195
|
+
const candidateNodes = snapshotOwnerId ? availableNodes.filter((node) => node.id === snapshotOwnerId) : availableNodes;
|
|
34196
|
+
const capableNodes = candidateNodes.filter((node) => nodeSupportsAgent(node, task.agent));
|
|
34152
34197
|
if (capableNodes.length === 0) continue;
|
|
34153
34198
|
const targetNode = this.pickLeastBusyNode(capableNodes, nodeLoad, previousNodeId);
|
|
34154
34199
|
if (!targetNode) continue;
|
|
@@ -36160,16 +36205,17 @@ var RestLeaderTaskReporter = class {
|
|
|
36160
36205
|
var import_node_child_process2 = require("child_process");
|
|
36161
36206
|
async function startWorkerTaskExecution(options) {
|
|
36162
36207
|
const { taskEngine, engineRegistry, nodeRegistry, eventBus, logger: logger27, workDir, leaderReporter } = options;
|
|
36163
|
-
const
|
|
36164
|
-
const existing = taskEngine.getTask(
|
|
36208
|
+
const incomingTask = { ...options.task };
|
|
36209
|
+
const existing = taskEngine.getTask(incomingTask.id);
|
|
36165
36210
|
if (existing && hasExecutionAlreadyStarted(existing.status)) {
|
|
36166
36211
|
logger27.warn("skipping duplicate task.execute for already-started task", {
|
|
36167
|
-
taskId:
|
|
36212
|
+
taskId: incomingTask.id,
|
|
36168
36213
|
status: existing.status,
|
|
36169
|
-
agent:
|
|
36214
|
+
agent: incomingTask.agent
|
|
36170
36215
|
});
|
|
36171
36216
|
return existing;
|
|
36172
36217
|
}
|
|
36218
|
+
const task = getExecutionTask(incomingTask, existing);
|
|
36173
36219
|
task.effectiveProjectPath = resolveTaskWorkDir(task.project, workDir);
|
|
36174
36220
|
task.branch = getCurrentGitBranch(task.effectiveProjectPath) ?? task.branch ?? null;
|
|
36175
36221
|
await taskEngine.executeTask(task);
|
|
@@ -36219,6 +36265,17 @@ async function startWorkerTaskExecution(options) {
|
|
|
36219
36265
|
}
|
|
36220
36266
|
return task;
|
|
36221
36267
|
}
|
|
36268
|
+
function getExecutionTask(incomingTask, existing) {
|
|
36269
|
+
if (!existing || !isJoinTaskSnapshot(incomingTask) || isJoinTaskSnapshot(existing)) {
|
|
36270
|
+
return incomingTask;
|
|
36271
|
+
}
|
|
36272
|
+
return {
|
|
36273
|
+
...existing,
|
|
36274
|
+
status: incomingTask.status,
|
|
36275
|
+
assignedTo: incomingTask.assignedTo,
|
|
36276
|
+
assignedNodeName: incomingTask.assignedNodeName
|
|
36277
|
+
};
|
|
36278
|
+
}
|
|
36222
36279
|
function hasExecutionAlreadyStarted(status) {
|
|
36223
36280
|
return status === "running" || status === "completed" || status === "failed" || status === "cancelled" || status === "archived";
|
|
36224
36281
|
}
|
|
@@ -37780,8 +37837,8 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
|
|
|
37780
37837
|
devtunnelEndpoint
|
|
37781
37838
|
});
|
|
37782
37839
|
}
|
|
37783
|
-
const tasks = this.taskEngine.listTasks().tasks;
|
|
37784
37840
|
const self2 = this.nodeRegistry.getSelf();
|
|
37841
|
+
const tasks = buildJoinTaskSnapshots(this.taskEngine.listTasks().tasks, self2.id);
|
|
37785
37842
|
const joinBody = {
|
|
37786
37843
|
id: self2.id,
|
|
37787
37844
|
endpoint: self2.endpoint,
|
|
@@ -37872,6 +37929,7 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
|
|
|
37872
37929
|
leaderEndpoint,
|
|
37873
37930
|
selfId: self2.id
|
|
37874
37931
|
});
|
|
37932
|
+
persistNodeStartupJoin(this.config.storage.path, void 0);
|
|
37875
37933
|
return;
|
|
37876
37934
|
}
|
|
37877
37935
|
if (leader && leaderEndpoint) {
|
|
@@ -43030,6 +43088,7 @@ var JoinTaskSchema = external_exports.object({
|
|
|
43030
43088
|
agent: external_exports.string(),
|
|
43031
43089
|
project: external_exports.string().nullable(),
|
|
43032
43090
|
effectiveProjectPath: external_exports.string().nullable(),
|
|
43091
|
+
branch: external_exports.string().nullable().optional(),
|
|
43033
43092
|
conversationKind: external_exports.enum(["meshyChat", "nativeSession"]).optional(),
|
|
43034
43093
|
payload: external_exports.record(external_exports.unknown()),
|
|
43035
43094
|
status: external_exports.enum(["pending", "assigned", "running", "completed", "failed", "cancelled", "archived"]),
|
|
@@ -43816,10 +43875,19 @@ function createClusterRoutes() {
|
|
|
43816
43875
|
});
|
|
43817
43876
|
}));
|
|
43818
43877
|
router.post("/leave", asyncHandler(async (req, res) => {
|
|
43819
|
-
const { nodeRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
43878
|
+
const { nodeRegistry, election, leaveCurrentCluster, logger: rootLogger } = req.app.locals.deps;
|
|
43820
43879
|
const log2 = rootLogger.child("cluster/leave");
|
|
43821
43880
|
const { nodeId } = req.body;
|
|
43822
43881
|
log2.info("received cluster leave request", { nodeId });
|
|
43882
|
+
if (!election.isLeader()) {
|
|
43883
|
+
if (!leaveCurrentCluster) {
|
|
43884
|
+
throw new MeshyError("VALIDATION_ERROR", "Leave flow is not available on this node", 501);
|
|
43885
|
+
}
|
|
43886
|
+
log2.info("handling cluster leave request as local follower detach", { requestedNodeId: nodeId });
|
|
43887
|
+
await leaveCurrentCluster();
|
|
43888
|
+
res.json({ ok: true });
|
|
43889
|
+
return;
|
|
43890
|
+
}
|
|
43823
43891
|
nodeRegistry.removeNode(nodeId);
|
|
43824
43892
|
res.json({ ok: true });
|
|
43825
43893
|
}));
|
|
@@ -44849,6 +44917,58 @@ function upgradeRuntimeAgentForDeps(deps, agent) {
|
|
|
44849
44917
|
return result;
|
|
44850
44918
|
}
|
|
44851
44919
|
|
|
44920
|
+
// ../../packages/api/src/node/runtime-restart-request.ts
|
|
44921
|
+
function parseRuntimeRestartRequest(value) {
|
|
44922
|
+
const body = isRecord4(value) ? value : {};
|
|
44923
|
+
const startArgs = parseRuntimeRestartStartArgs(body.startArgs);
|
|
44924
|
+
return {
|
|
44925
|
+
reason: body.reason === "update" ? "update" : "restart",
|
|
44926
|
+
...startArgs && { startArgs }
|
|
44927
|
+
};
|
|
44928
|
+
}
|
|
44929
|
+
function parseRuntimeRestartStartArgs(value) {
|
|
44930
|
+
if (value === void 0) return void 0;
|
|
44931
|
+
if (!isRecord4(value)) {
|
|
44932
|
+
throw new MeshyError("VALIDATION_ERROR", "Runtime restart startArgs must be an object", 400);
|
|
44933
|
+
}
|
|
44934
|
+
const startArgs = {};
|
|
44935
|
+
if (value.port !== void 0) {
|
|
44936
|
+
const port = value.port;
|
|
44937
|
+
if (typeof port !== "number" || !Number.isInteger(port) || port <= 0) {
|
|
44938
|
+
throw new MeshyError("VALIDATION_ERROR", "Runtime restart port must be a positive integer", 400);
|
|
44939
|
+
}
|
|
44940
|
+
startArgs.port = port;
|
|
44941
|
+
}
|
|
44942
|
+
for (const key of ["name", "join", "workDir", "config"]) {
|
|
44943
|
+
const parsed = parseOptionalString(value[key], key);
|
|
44944
|
+
if (parsed !== void 0) startArgs[key] = parsed;
|
|
44945
|
+
}
|
|
44946
|
+
if (value.transport !== void 0) {
|
|
44947
|
+
if (value.transport !== "direct" && value.transport !== "devtunnel" && value.transport !== "tailscale") {
|
|
44948
|
+
throw new MeshyError("VALIDATION_ERROR", "Runtime restart transport must be direct, devtunnel, or tailscale", 400);
|
|
44949
|
+
}
|
|
44950
|
+
startArgs.transport = value.transport;
|
|
44951
|
+
}
|
|
44952
|
+
if (value.disableAuth !== void 0) {
|
|
44953
|
+
if (typeof value.disableAuth !== "boolean") {
|
|
44954
|
+
throw new MeshyError("VALIDATION_ERROR", "Runtime restart disableAuth must be a boolean", 400);
|
|
44955
|
+
}
|
|
44956
|
+
startArgs.disableAuth = value.disableAuth;
|
|
44957
|
+
}
|
|
44958
|
+
return Object.keys(startArgs).length > 0 ? startArgs : void 0;
|
|
44959
|
+
}
|
|
44960
|
+
function parseOptionalString(value, key) {
|
|
44961
|
+
if (value === void 0) return void 0;
|
|
44962
|
+
if (typeof value !== "string") {
|
|
44963
|
+
throw new MeshyError("VALIDATION_ERROR", `Runtime restart ${key} must be a string`, 400);
|
|
44964
|
+
}
|
|
44965
|
+
const trimmed = value.trim();
|
|
44966
|
+
return trimmed || void 0;
|
|
44967
|
+
}
|
|
44968
|
+
function isRecord4(value) {
|
|
44969
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
44970
|
+
}
|
|
44971
|
+
|
|
44852
44972
|
// ../../packages/api/src/node/node-operation-service.ts
|
|
44853
44973
|
var LEADER_REPORT_RETRY_MS = 5e3;
|
|
44854
44974
|
var OPERATION_COMMIT_EFFECT = /* @__PURE__ */ Symbol("operationCommitEffect");
|
|
@@ -45062,7 +45182,8 @@ function runAgentUpgradeOperation(operation, deps) {
|
|
|
45062
45182
|
function runRuntimeRestartOperation(operation, deps) {
|
|
45063
45183
|
if (!deps.restartRuntime) throw new Error("Runtime restart is not available for this node");
|
|
45064
45184
|
const reason = readPayloadString(operation, "reason") === "update" ? "update" : "restart";
|
|
45065
|
-
|
|
45185
|
+
const startArgs = readPayloadStartArgs(operation);
|
|
45186
|
+
return deps.restartRuntime({ reason, ...startArgs && { startArgs }, deferShutdown: true }).then(
|
|
45066
45187
|
({ completeShutdown, ...result }) => operationCommitEffect(result, completeShutdown)
|
|
45067
45188
|
);
|
|
45068
45189
|
}
|
|
@@ -45109,6 +45230,11 @@ function readPayloadBoolean(operation, key, fallback) {
|
|
|
45109
45230
|
const value = payload[key];
|
|
45110
45231
|
return typeof value === "boolean" ? value : fallback;
|
|
45111
45232
|
}
|
|
45233
|
+
function readPayloadStartArgs(operation) {
|
|
45234
|
+
const payload = operation.payload;
|
|
45235
|
+
if (!payload || typeof payload !== "object") return void 0;
|
|
45236
|
+
return parseRuntimeRestartStartArgs(payload.startArgs);
|
|
45237
|
+
}
|
|
45112
45238
|
function readSettingsSnapshot(value) {
|
|
45113
45239
|
if (!value || typeof value !== "object") return void 0;
|
|
45114
45240
|
const snapshot = value.settingsSnapshot;
|
|
@@ -45276,7 +45402,7 @@ function toLegacyWorkerControl2(message) {
|
|
|
45276
45402
|
}
|
|
45277
45403
|
|
|
45278
45404
|
// ../../packages/api/src/tasks/task-route-utils.ts
|
|
45279
|
-
function
|
|
45405
|
+
function isRecord5(value) {
|
|
45280
45406
|
return typeof value === "object" && value !== null;
|
|
45281
45407
|
}
|
|
45282
45408
|
function restoreTaskState(taskEngine, task) {
|
|
@@ -45343,7 +45469,7 @@ function normalizeStructuredValue(value) {
|
|
|
45343
45469
|
if (Array.isArray(value)) {
|
|
45344
45470
|
return value.map((entry) => normalizeStructuredValue(entry));
|
|
45345
45471
|
}
|
|
45346
|
-
if (!
|
|
45472
|
+
if (!isRecord5(value)) {
|
|
45347
45473
|
return value;
|
|
45348
45474
|
}
|
|
45349
45475
|
return Object.fromEntries(
|
|
@@ -45352,20 +45478,20 @@ function normalizeStructuredValue(value) {
|
|
|
45352
45478
|
}
|
|
45353
45479
|
function getTranscriptEventSignature(event) {
|
|
45354
45480
|
if (event.type === "user") {
|
|
45355
|
-
const signature = getTaskUserMessageSignature(
|
|
45481
|
+
const signature = getTaskUserMessageSignature(isRecord5(event.message) ? event.message.content : event.message) ?? getTaskUserMessageSignature(event.content);
|
|
45356
45482
|
return signature ? `user:${signature}` : null;
|
|
45357
45483
|
}
|
|
45358
45484
|
if (event.type === "assistant") {
|
|
45359
45485
|
if (typeof event.message === "string") {
|
|
45360
45486
|
return `assistant:${JSON.stringify(event.message)}`;
|
|
45361
45487
|
}
|
|
45362
|
-
if (
|
|
45488
|
+
if (isRecord5(event.message) && "content" in event.message) {
|
|
45363
45489
|
return `assistant:${JSON.stringify(normalizeStructuredValue(event.message.content))}`;
|
|
45364
45490
|
}
|
|
45365
45491
|
if (Array.isArray(event.content)) {
|
|
45366
45492
|
return `assistant:${JSON.stringify(normalizeStructuredValue(event.content))}`;
|
|
45367
45493
|
}
|
|
45368
|
-
if (
|
|
45494
|
+
if (isRecord5(event.message)) {
|
|
45369
45495
|
return `assistant:${JSON.stringify(normalizeStructuredValue(event.message))}`;
|
|
45370
45496
|
}
|
|
45371
45497
|
}
|
|
@@ -47162,9 +47288,6 @@ async function sendNodeAgentUpgrade(req, res, nodeId, agentParam) {
|
|
|
47162
47288
|
}
|
|
47163
47289
|
|
|
47164
47290
|
// ../../packages/api/src/routes/node-runtime.ts
|
|
47165
|
-
function parseRestartReason(value) {
|
|
47166
|
-
return value === "update" ? "update" : "restart";
|
|
47167
|
-
}
|
|
47168
47291
|
async function sendNodeRuntimeRestart(req, res, nodeId) {
|
|
47169
47292
|
const deps = req.app.locals.deps;
|
|
47170
47293
|
const self2 = deps.nodeRegistry.getSelf();
|
|
@@ -47176,9 +47299,9 @@ async function sendNodeRuntimeRestart(req, res, nodeId) {
|
|
|
47176
47299
|
if (!node) {
|
|
47177
47300
|
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
47178
47301
|
}
|
|
47179
|
-
const
|
|
47302
|
+
const restartRequest = parseRuntimeRestartRequest(req.body);
|
|
47180
47303
|
const operations = getNodeOperationService(deps);
|
|
47181
|
-
const operation = operations.create("runtime.restart", nodeId, {
|
|
47304
|
+
const operation = operations.create("runtime.restart", nodeId, { ...restartRequest });
|
|
47182
47305
|
if (isSelf) {
|
|
47183
47306
|
operations.runLocal(operation.id);
|
|
47184
47307
|
} else {
|
|
@@ -48099,8 +48222,10 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
48099
48222
|
if (!task && !proxyRequest.isProxy && await maybeProxyReadToLeader(req, res)) return;
|
|
48100
48223
|
const selfId = nodeRegistry.getSelf()?.id;
|
|
48101
48224
|
const isLeader = nodeRegistry.isLeader();
|
|
48225
|
+
const snapshotOwnerId = task ? getJoinTaskSnapshotOwnerId(task) : null;
|
|
48226
|
+
const proxyNodeId = task?.assignedTo ?? snapshotOwnerId;
|
|
48102
48227
|
const isFollowerRemoteTask = !isLeader && !!(task?.assignedTo && task.assignedTo !== selfId);
|
|
48103
|
-
const needsProxy = isLeader && !!(
|
|
48228
|
+
const needsProxy = isLeader && !!(proxyNodeId && proxyNodeId !== selfId);
|
|
48104
48229
|
if (proxyRequest.isProxy) {
|
|
48105
48230
|
log2.info("received proxied task logs request", {
|
|
48106
48231
|
taskId,
|
|
@@ -48118,6 +48243,7 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
48118
48243
|
log2.debug("log request", {
|
|
48119
48244
|
taskId,
|
|
48120
48245
|
assignedTo: task?.assignedTo,
|
|
48246
|
+
snapshotOwnerId,
|
|
48121
48247
|
selfId,
|
|
48122
48248
|
isLeader,
|
|
48123
48249
|
needsProxy
|
|
@@ -48141,20 +48267,21 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
48141
48267
|
selfId
|
|
48142
48268
|
});
|
|
48143
48269
|
}
|
|
48144
|
-
|
|
48145
|
-
|
|
48146
|
-
const node = nodeRegistry.getNode(assignedTo);
|
|
48270
|
+
if (needsProxy && proxyNodeId) {
|
|
48271
|
+
const node = nodeRegistry.getNode(proxyNodeId);
|
|
48147
48272
|
log2.debug("proxy target", { nodeId: node?.id, endpoint: node?.endpoint, devtunnel: node?.devtunnelEndpoint, status: node?.status });
|
|
48148
48273
|
if (node) {
|
|
48149
|
-
|
|
48150
|
-
|
|
48151
|
-
|
|
48152
|
-
|
|
48153
|
-
|
|
48274
|
+
if (task.assignedTo === proxyNodeId && !snapshotOwnerId) {
|
|
48275
|
+
const seededLogs = await seedTaskSnapshotOnWorker(task, [], node, log2).catch((err) => {
|
|
48276
|
+
log2.warn("failed to seed task snapshot before task logs proxy", {
|
|
48277
|
+
taskId,
|
|
48278
|
+
assignedTo: proxyNodeId,
|
|
48279
|
+
...describeProxyError3(err)
|
|
48280
|
+
});
|
|
48281
|
+
return [];
|
|
48154
48282
|
});
|
|
48155
|
-
|
|
48156
|
-
}
|
|
48157
|
-
if (seededLogs.length > 0) recordLocalTaskLogs(engineRegistry, task, seededLogs);
|
|
48283
|
+
if (seededLogs.length > 0) recordLocalTaskLogs(engineRegistry, task, seededLogs);
|
|
48284
|
+
}
|
|
48158
48285
|
const proxyPath = `/api/tasks/${taskId}/logs?after=${after}`;
|
|
48159
48286
|
try {
|
|
48160
48287
|
const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
|
|
@@ -48168,7 +48295,7 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
48168
48295
|
const proxyUrl = `${endpoint}${proxyPath}`;
|
|
48169
48296
|
log2.info("proxying task logs request", {
|
|
48170
48297
|
taskId,
|
|
48171
|
-
assignedTo,
|
|
48298
|
+
assignedTo: proxyNodeId,
|
|
48172
48299
|
endpoint,
|
|
48173
48300
|
proxyPath,
|
|
48174
48301
|
url: proxyUrl
|
|
@@ -48181,11 +48308,11 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
48181
48308
|
} catch (err) {
|
|
48182
48309
|
log2.warn("task logs proxy failed; falling back to keepalive control", {
|
|
48183
48310
|
taskId,
|
|
48184
|
-
assignedTo,
|
|
48311
|
+
assignedTo: proxyNodeId,
|
|
48185
48312
|
timeoutMs: TASK_LOG_PROXY_TIMEOUT_MS,
|
|
48186
48313
|
...describeProxyError3(err)
|
|
48187
48314
|
});
|
|
48188
|
-
const fallback = await requestTaskLogsOverKeepalive(heartbeat,
|
|
48315
|
+
const fallback = await requestTaskLogsOverKeepalive(heartbeat, proxyNodeId, task, after);
|
|
48189
48316
|
if (fallback) {
|
|
48190
48317
|
sendWorkerControlResponse(res, fallback);
|
|
48191
48318
|
return;
|
|
@@ -48576,6 +48703,8 @@ var TERMINAL_STATUSES3 = /* @__PURE__ */ new Set(["completed", "failed", "cancel
|
|
|
48576
48703
|
var ARCHIVABLE_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
|
|
48577
48704
|
var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "assigned", "running"]);
|
|
48578
48705
|
var TASK_DELETE_NOTIFY_TIMEOUT_MS = 1500;
|
|
48706
|
+
var TASK_DETAIL_PROXY_TIMEOUT_MS = 1e4;
|
|
48707
|
+
var TASK_DETAIL_PROXY_HEADER = "x-meshy-task-detail-proxy";
|
|
48579
48708
|
function shouldGenerateTitle(task) {
|
|
48580
48709
|
return task.payload.titleSource === "derived";
|
|
48581
48710
|
}
|
|
@@ -48686,6 +48815,62 @@ function withShareMetadata(task, taskEngine, shareOrigin) {
|
|
|
48686
48815
|
function toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin) {
|
|
48687
48816
|
return withShareMetadata(withAssignedNodeMetadata(task, nodeRegistry), taskEngine, shareOrigin);
|
|
48688
48817
|
}
|
|
48818
|
+
async function proxyJoinSnapshotTaskDetail(deps) {
|
|
48819
|
+
if (deps.req.get(TASK_DETAIL_PROXY_HEADER) === "1") {
|
|
48820
|
+
return null;
|
|
48821
|
+
}
|
|
48822
|
+
const ownerNodeId = getJoinTaskSnapshotOwnerId(deps.task);
|
|
48823
|
+
const selfId = deps.nodeRegistry.getSelf()?.id;
|
|
48824
|
+
if (!ownerNodeId || ownerNodeId === selfId) {
|
|
48825
|
+
return null;
|
|
48826
|
+
}
|
|
48827
|
+
const owner = deps.nodeRegistry.getNode(ownerNodeId);
|
|
48828
|
+
const log2 = deps.logger.child("tasks/detail");
|
|
48829
|
+
if (!owner) {
|
|
48830
|
+
log2.warn("join snapshot owner is unavailable for task detail proxy", {
|
|
48831
|
+
taskId: deps.task.id,
|
|
48832
|
+
ownerNodeId
|
|
48833
|
+
});
|
|
48834
|
+
return null;
|
|
48835
|
+
}
|
|
48836
|
+
const proxyPath = `/api/tasks/${encodeURIComponent(deps.task.id)}`;
|
|
48837
|
+
try {
|
|
48838
|
+
const { endpoint, response } = await fetchNodeWithFallback(
|
|
48839
|
+
owner,
|
|
48840
|
+
proxyPath,
|
|
48841
|
+
{ method: "GET", headers: { [TASK_DETAIL_PROXY_HEADER]: "1" } },
|
|
48842
|
+
TASK_DETAIL_PROXY_TIMEOUT_MS,
|
|
48843
|
+
void 0,
|
|
48844
|
+
{ preferPublicEndpoint: true }
|
|
48845
|
+
);
|
|
48846
|
+
if (!response.ok) {
|
|
48847
|
+
log2.warn("join snapshot task detail proxy returned non-ok response", {
|
|
48848
|
+
taskId: deps.task.id,
|
|
48849
|
+
ownerNodeId,
|
|
48850
|
+
endpoint,
|
|
48851
|
+
statusCode: response.status
|
|
48852
|
+
});
|
|
48853
|
+
return null;
|
|
48854
|
+
}
|
|
48855
|
+
const fullTask = await response.json();
|
|
48856
|
+
if (fullTask.id !== deps.task.id) {
|
|
48857
|
+
log2.warn("join snapshot task detail proxy returned a different task id", {
|
|
48858
|
+
taskId: deps.task.id,
|
|
48859
|
+
ownerNodeId,
|
|
48860
|
+
returnedTaskId: fullTask.id
|
|
48861
|
+
});
|
|
48862
|
+
return null;
|
|
48863
|
+
}
|
|
48864
|
+
return fullTask;
|
|
48865
|
+
} catch (err) {
|
|
48866
|
+
log2.warn("join snapshot task detail proxy failed", {
|
|
48867
|
+
taskId: deps.task.id,
|
|
48868
|
+
ownerNodeId,
|
|
48869
|
+
error: err instanceof Error ? err.message : String(err)
|
|
48870
|
+
});
|
|
48871
|
+
return null;
|
|
48872
|
+
}
|
|
48873
|
+
}
|
|
48689
48874
|
function buildShareUrl(origin, shareId) {
|
|
48690
48875
|
return `${origin.replace(/\/+$/, "")}/shared/tasks/${encodeURIComponent(shareId)}`;
|
|
48691
48876
|
}
|
|
@@ -48809,14 +48994,15 @@ function createTaskRoutes() {
|
|
|
48809
48994
|
res.json({ results });
|
|
48810
48995
|
}));
|
|
48811
48996
|
router.get("/:id", asyncHandler6(async (req, res) => {
|
|
48812
|
-
const { taskEngine, nodeRegistry, shareOrigin } = req.app.locals.deps;
|
|
48997
|
+
const { taskEngine, nodeRegistry, shareOrigin, logger: logger27 } = req.app.locals.deps;
|
|
48813
48998
|
const taskId = req.params.id;
|
|
48814
48999
|
const task = taskEngine.getTask(taskId);
|
|
48815
49000
|
if (!task) {
|
|
48816
49001
|
if (await maybeProxyReadToLeader(req, res)) return;
|
|
48817
49002
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
48818
49003
|
}
|
|
48819
|
-
|
|
49004
|
+
const fullTask = await proxyJoinSnapshotTaskDetail({ task, req, logger: logger27, nodeRegistry });
|
|
49005
|
+
res.json(toTaskResponse(fullTask ?? task, nodeRegistry, taskEngine, shareOrigin));
|
|
48820
49006
|
}));
|
|
48821
49007
|
router.post("/:id/share", asyncHandler6(async (req, res) => {
|
|
48822
49008
|
const { taskEngine, ensureShareTunnel } = req.app.locals.deps;
|
|
@@ -49491,9 +49677,8 @@ function createSystemRoutes() {
|
|
|
49491
49677
|
if (!restartRuntime) {
|
|
49492
49678
|
throw new MeshyError("VALIDATION_ERROR", "Runtime restart is not available for this node", 501);
|
|
49493
49679
|
}
|
|
49494
|
-
const
|
|
49495
|
-
const
|
|
49496
|
-
const result = await restartRuntime({ reason });
|
|
49680
|
+
const restartRequest = parseRuntimeRestartRequest(req.body);
|
|
49681
|
+
const result = await restartRuntime(restartRequest);
|
|
49497
49682
|
res.status(202).json(result);
|
|
49498
49683
|
}));
|
|
49499
49684
|
router.post("/runtime/stop", asyncHandler9(async (req, res) => {
|
|
@@ -49672,6 +49857,9 @@ function createNodeOperationRoutes() {
|
|
|
49672
49857
|
var JSON_BODY_LIMIT = "1mb";
|
|
49673
49858
|
var JSON_BODY_LIMIT_LARGE = "25mb";
|
|
49674
49859
|
var TRUSTED_LOCAL_HOSTS2 = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
|
|
49860
|
+
function usesLargeJsonBodyLimit(pathname) {
|
|
49861
|
+
return pathname === "/api/cluster/join" || pathname === "/api/node" || pathname.startsWith("/api/node/") || pathname === "/api/tasks" || pathname.startsWith("/api/tasks/") || pathname === "/api/worker" || pathname.startsWith("/api/worker/");
|
|
49862
|
+
}
|
|
49675
49863
|
function normalizeHost2(value) {
|
|
49676
49864
|
const trimmed = value?.trim().toLowerCase();
|
|
49677
49865
|
return trimmed ? trimmed.replace(/:\d+$/, "") : void 0;
|
|
@@ -49798,7 +49986,12 @@ function createServer2(deps) {
|
|
|
49798
49986
|
staticMiddleware(req, res, next);
|
|
49799
49987
|
});
|
|
49800
49988
|
}
|
|
49801
|
-
|
|
49989
|
+
const defaultJsonParser = import_express14.default.json({ limit: JSON_BODY_LIMIT });
|
|
49990
|
+
const largeJsonParser = import_express14.default.json({ limit: JSON_BODY_LIMIT_LARGE });
|
|
49991
|
+
app.use((req, res, next) => {
|
|
49992
|
+
const parser = usesLargeJsonBodyLimit(req.path) ? largeJsonParser : defaultJsonParser;
|
|
49993
|
+
parser(req, res, next);
|
|
49994
|
+
});
|
|
49802
49995
|
app.use(createAuthMiddleware(authConfig));
|
|
49803
49996
|
app.use((req, res, next) => {
|
|
49804
49997
|
void (async () => {
|
|
@@ -49824,14 +50017,13 @@ function createServer2(deps) {
|
|
|
49824
50017
|
taskEngine: deps.taskEngine,
|
|
49825
50018
|
logger: deps.logger
|
|
49826
50019
|
}));
|
|
49827
|
-
const largeBodyParser = import_express14.default.json({ limit: JSON_BODY_LIMIT_LARGE });
|
|
49828
50020
|
app.use("/api/cluster", createClusterRoutes());
|
|
49829
50021
|
app.use("/api/cluster-control", createClusterControlRoutes());
|
|
49830
|
-
app.use("/api/node",
|
|
50022
|
+
app.use("/api/node", createNodeMessageRoutes());
|
|
49831
50023
|
app.use("/api/nodes", createNodeRoutes());
|
|
49832
|
-
app.use("/api/tasks",
|
|
50024
|
+
app.use("/api/tasks", createTaskRoutes());
|
|
49833
50025
|
app.use("/api/shared", createSharedRoutes());
|
|
49834
|
-
app.use("/api/worker",
|
|
50026
|
+
app.use("/api/worker", createWorkerRoutes());
|
|
49835
50027
|
app.use("/api/system", createSystemRoutes());
|
|
49836
50028
|
app.use("/api/node-operations", createNodeOperationRoutes());
|
|
49837
50029
|
app.use("/api/events", createEventRoutes());
|
|
@@ -50875,6 +51067,9 @@ function buildRuntimeMetadata(storagePath) {
|
|
|
50875
51067
|
var fs22 = __toESM(require("fs"), 1);
|
|
50876
51068
|
var nodePath2 = __toESM(require("path"), 1);
|
|
50877
51069
|
var import_node_child_process14 = require("child_process");
|
|
51070
|
+
function resolveRuntimeRestartStartArgs(hydratedArgs, restartArgs) {
|
|
51071
|
+
return restartArgs ? { ...restartArgs } : hydratedArgs;
|
|
51072
|
+
}
|
|
50878
51073
|
var runtimeUpdateCache = /* @__PURE__ */ new Map();
|
|
50879
51074
|
var RESTARTER_SOURCE = String.raw`
|
|
50880
51075
|
const { spawn } = require('node:child_process');
|
|
@@ -51842,7 +52037,7 @@ async function startNode(args) {
|
|
|
51842
52037
|
cwd: process.cwd(),
|
|
51843
52038
|
env: process.env,
|
|
51844
52039
|
localDashboardOrigin,
|
|
51845
|
-
startArgs: hydratedArgs.args,
|
|
52040
|
+
startArgs: resolveRuntimeRestartStartArgs(hydratedArgs.args, request.startArgs),
|
|
51846
52041
|
storagePath: config.storage.path
|
|
51847
52042
|
});
|
|
51848
52043
|
scheduleRuntimeRestart(plan, { parentPid: process.pid });
|
package/package.json
CHANGED
package/runtime-metadata.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "meshy-node",
|
|
3
|
-
"packageVersion": "0.4.
|
|
3
|
+
"packageVersion": "0.4.6",
|
|
4
4
|
"packages": {
|
|
5
5
|
"workspace": {
|
|
6
6
|
"name": "meshy",
|
|
7
|
-
"version": "0.4.
|
|
7
|
+
"version": "0.4.6"
|
|
8
8
|
},
|
|
9
9
|
"node": {
|
|
10
10
|
"name": "meshy-node",
|
|
11
|
-
"version": "0.4.
|
|
11
|
+
"version": "0.4.6"
|
|
12
12
|
},
|
|
13
13
|
"core": {
|
|
14
14
|
"name": "@meshy/core",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"repository": {
|
|
27
27
|
"url": "https://github.com/ai-microsoft/meshy",
|
|
28
|
-
"branch": "
|
|
29
|
-
"commit": "
|
|
28
|
+
"branch": "fixNodeJoin",
|
|
29
|
+
"commit": "ea67bf5"
|
|
30
30
|
}
|
|
31
31
|
}
|