meshy-node 0.10.7 → 0.10.8
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-BA5_31Nu.js +181 -0
- package/dashboard/assets/{DashboardShared-BUUqTMMG.js → DashboardShared-BfK1KyJO.js} +18 -18
- package/dashboard/assets/{DiffTab-BJ-QDAVa.js → DiffTab-BPQY3AYd.js} +2 -2
- package/dashboard/assets/{FilesTab-CXyf-FqN.js → FilesTab-91w4HaID.js} +2 -2
- package/dashboard/assets/{MarkdownPreviewFrame-CFCsFLMN.js → MarkdownPreviewFrame-C56qjNyn.js} +1 -1
- package/dashboard/assets/{PreviewTab-hYU-Sg4s.js → PreviewTab-DQ4yhJji.js} +2 -2
- package/dashboard/assets/SharedConversationPage-hiwRfWZA.js +2 -0
- package/dashboard/assets/{file-Ct6iLy28.js → file-DQcCuz7j.js} +1 -1
- package/dashboard/assets/index-BvnWYZW6.js +346 -0
- package/dashboard/assets/index-By1kKB26.css +1 -0
- package/dashboard/index.html +2 -2
- package/main.cjs +601 -151
- package/package.json +1 -1
- package/runtime-metadata.json +4 -4
- package/dashboard/assets/DashboardPage-B8aG_22p.js +0 -176
- package/dashboard/assets/SharedConversationPage-Bb7cY7t7.js +0 -2
- package/dashboard/assets/index-0SJFGvhq.js +0 -346
- package/dashboard/assets/index-Br15-PXW.css +0 -1
package/main.cjs
CHANGED
|
@@ -136339,6 +136339,8 @@ var fs3 = __toESM(require("fs"), 1);
|
|
|
136339
136339
|
var os3 = __toESM(require("os"), 1);
|
|
136340
136340
|
var path3 = __toESM(require("path"), 1);
|
|
136341
136341
|
var STARTUP_TRANSPORTS = /* @__PURE__ */ new Set(["direct", "devtunnel", "tailscale"]);
|
|
136342
|
+
var DEFAULT_TASK_AGENTS = /* @__PURE__ */ new Set(["codex", "claudecode", "copilot"]);
|
|
136343
|
+
var DEFAULT_NODE_TASK_AGENT = "codex";
|
|
136342
136344
|
function getDeviceNodeName() {
|
|
136343
136345
|
return os3.hostname();
|
|
136344
136346
|
}
|
|
@@ -136408,6 +136410,9 @@ function normalizeString(value) {
|
|
|
136408
136410
|
function normalizeStartupTransport(value) {
|
|
136409
136411
|
return typeof value === "string" && STARTUP_TRANSPORTS.has(value) ? value : void 0;
|
|
136410
136412
|
}
|
|
136413
|
+
function normalizeDefaultTaskAgent(value) {
|
|
136414
|
+
return typeof value === "string" && DEFAULT_TASK_AGENTS.has(value) ? value : void 0;
|
|
136415
|
+
}
|
|
136411
136416
|
function normalizeStartupMetadata(startup) {
|
|
136412
136417
|
return {
|
|
136413
136418
|
port: normalizePositiveInteger(startup?.port),
|
|
@@ -136445,6 +136450,9 @@ function resolveDefaultNodeName(storagePath, deviceName = getDeviceNodeName()) {
|
|
|
136445
136450
|
const preferredName = resolvePersistedDefaultNodeName(storagePath);
|
|
136446
136451
|
return preferredName && preferredName.length > 0 ? preferredName : deviceName;
|
|
136447
136452
|
}
|
|
136453
|
+
function resolveNodeDefaultTaskAgent(storagePath) {
|
|
136454
|
+
return normalizeDefaultTaskAgent(readNodeMetadata(storagePath).defaultTaskAgent) ?? DEFAULT_NODE_TASK_AGENT;
|
|
136455
|
+
}
|
|
136448
136456
|
function persistDefaultNodeName(storagePath, name2, deviceName = getDeviceNodeName()) {
|
|
136449
136457
|
const metadata = readNodeMetadata(storagePath);
|
|
136450
136458
|
const normalizedName = name2.trim();
|
|
@@ -136455,6 +136463,11 @@ function persistDefaultNodeName(storagePath, name2, deviceName = getDeviceNodeNa
|
|
|
136455
136463
|
}
|
|
136456
136464
|
writeNodeMetadata(storagePath, metadata);
|
|
136457
136465
|
}
|
|
136466
|
+
function persistNodeDefaultTaskAgent(storagePath, agent) {
|
|
136467
|
+
const metadata = readNodeMetadata(storagePath);
|
|
136468
|
+
metadata.defaultTaskAgent = agent;
|
|
136469
|
+
writeNodeMetadata(storagePath, metadata);
|
|
136470
|
+
}
|
|
136458
136471
|
function resolveNodeAuthMetadata(storagePath) {
|
|
136459
136472
|
return normalizeAuthMetadata(readNodeMetadata(storagePath).auth);
|
|
136460
136473
|
}
|
|
@@ -136958,6 +136971,7 @@ function parseTaskQueuedMessages(value) {
|
|
|
136958
136971
|
messages.push({
|
|
136959
136972
|
id: entry.id,
|
|
136960
136973
|
content: clone(entry.content),
|
|
136974
|
+
...typeof entry.targetAgent === "string" ? { targetAgent: entry.targetAgent } : {},
|
|
136961
136975
|
createdAt: entry.createdAt
|
|
136962
136976
|
});
|
|
136963
136977
|
}
|
|
@@ -138439,7 +138453,7 @@ var TaskEngine = class {
|
|
|
138439
138453
|
});
|
|
138440
138454
|
return true;
|
|
138441
138455
|
}
|
|
138442
|
-
enqueueTaskMessage(taskId, content3) {
|
|
138456
|
+
enqueueTaskMessage(taskId, content3, targetAgent) {
|
|
138443
138457
|
const task = this.store.getTask(taskId);
|
|
138444
138458
|
if (!task) {
|
|
138445
138459
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
@@ -138454,7 +138468,12 @@ var TaskEngine = class {
|
|
|
138454
138468
|
const now = Date.now();
|
|
138455
138469
|
const queuedMessages = [
|
|
138456
138470
|
...task.queuedMessages ?? [],
|
|
138457
|
-
{
|
|
138471
|
+
{
|
|
138472
|
+
id: (0, import_node_crypto5.randomUUID)(),
|
|
138473
|
+
content: content3,
|
|
138474
|
+
...targetAgent ? { targetAgent } : {},
|
|
138475
|
+
createdAt: now
|
|
138476
|
+
}
|
|
138458
138477
|
];
|
|
138459
138478
|
const updated = this.store.updateTask(taskId, { queuedMessages, updatedAt: now });
|
|
138460
138479
|
this.eventBus.emit("task.updated", {
|
|
@@ -140021,6 +140040,31 @@ var ExecutionEngine = class {
|
|
|
140021
140040
|
await Promise.all([...this.logWrites.values()]);
|
|
140022
140041
|
}
|
|
140023
140042
|
}
|
|
140043
|
+
async getLogLineCount(taskId) {
|
|
140044
|
+
const logPath = this.getLogPath(taskId);
|
|
140045
|
+
try {
|
|
140046
|
+
const content3 = await fs7.promises.readFile(logPath, "utf-8");
|
|
140047
|
+
const trimmed = content3.trim();
|
|
140048
|
+
return trimmed ? trimmed.split("\n").filter(Boolean).length : 0;
|
|
140049
|
+
} catch (error2) {
|
|
140050
|
+
if (error2.code === "ENOENT") return 0;
|
|
140051
|
+
throw error2;
|
|
140052
|
+
}
|
|
140053
|
+
}
|
|
140054
|
+
async flushLogsAndEmitReady(taskId) {
|
|
140055
|
+
try {
|
|
140056
|
+
await this.waitForLogWrites();
|
|
140057
|
+
const total = await this.getLogLineCount(taskId);
|
|
140058
|
+
this.eventBus.emit("task.logs.ready", { taskId, total });
|
|
140059
|
+
return total;
|
|
140060
|
+
} catch (error2) {
|
|
140061
|
+
this.logger.warn("failed to emit task log readiness checkpoint", {
|
|
140062
|
+
taskId,
|
|
140063
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
140064
|
+
});
|
|
140065
|
+
return 0;
|
|
140066
|
+
}
|
|
140067
|
+
}
|
|
140024
140068
|
getLogPath(taskId) {
|
|
140025
140069
|
return path7.join(this.logDir, `${taskId}.jsonl`);
|
|
140026
140070
|
}
|
|
@@ -140886,9 +140930,59 @@ function nonEmptyString(value) {
|
|
|
140886
140930
|
function getNativeHistorySessionId(payload) {
|
|
140887
140931
|
return nonEmptyString(payload?.nativeSessionId) || nonEmptyString(payload?.sessionId);
|
|
140888
140932
|
}
|
|
140889
|
-
function
|
|
140933
|
+
function isRecord5(value) {
|
|
140934
|
+
return typeof value === "object" && value !== null;
|
|
140935
|
+
}
|
|
140936
|
+
function getAgentSessions(payload) {
|
|
140937
|
+
const raw3 = payload.agentSessions;
|
|
140938
|
+
if (!isRecord5(raw3)) return {};
|
|
140939
|
+
const sessions = {};
|
|
140940
|
+
for (const [agent, value] of Object.entries(raw3)) {
|
|
140941
|
+
if (!isRecord5(value)) continue;
|
|
140942
|
+
const sessionId = nonEmptyString(value.sessionId);
|
|
140943
|
+
const cwd = nonEmptyString(value.cwd);
|
|
140944
|
+
if (!agent || !sessionId || !cwd) continue;
|
|
140945
|
+
sessions[agent] = { sessionId, cwd };
|
|
140946
|
+
}
|
|
140947
|
+
return sessions;
|
|
140948
|
+
}
|
|
140949
|
+
function getPersistedAgentSession(task, agent) {
|
|
140890
140950
|
const payload = task?.payload ?? {};
|
|
140951
|
+
const sessions = getAgentSessions(payload);
|
|
140952
|
+
const session = sessions[agent];
|
|
140953
|
+
if (session) return session;
|
|
140954
|
+
if (Object.keys(sessions).length > 0 || task?.agent !== agent) {
|
|
140955
|
+
return null;
|
|
140956
|
+
}
|
|
140957
|
+
const legacySessionId = nonEmptyString(payload.sessionId);
|
|
140958
|
+
if (!legacySessionId) return null;
|
|
140959
|
+
return {
|
|
140960
|
+
sessionId: legacySessionId,
|
|
140961
|
+
cwd: nonEmptyString(payload.sessionCwd)
|
|
140962
|
+
};
|
|
140963
|
+
}
|
|
140964
|
+
function canUseSessionLogEventForAgent(task, agent, event) {
|
|
140965
|
+
const eventAgent = nonEmptyString(event.agent);
|
|
140966
|
+
if (eventAgent) return eventAgent === agent;
|
|
140967
|
+
const sessions = getAgentSessions(task?.payload ?? {});
|
|
140968
|
+
return Object.keys(sessions).length === 0 && task?.agent === agent;
|
|
140969
|
+
}
|
|
140970
|
+
function buildPersistedSessionPayload(task, sessionId, cwd, agent) {
|
|
140971
|
+
const payload = task?.payload ?? {};
|
|
140972
|
+
const activeAgent = nonEmptyString(agent);
|
|
140891
140973
|
const nextPayload = { ...payload, sessionId, sessionCwd: cwd };
|
|
140974
|
+
if (activeAgent) {
|
|
140975
|
+
const agentSessions = getAgentSessions(payload);
|
|
140976
|
+
const taskAgent = nonEmptyString(task?.agent);
|
|
140977
|
+
const legacySessionId = nonEmptyString(payload.sessionId);
|
|
140978
|
+
const legacyCwd = nonEmptyString(payload.sessionCwd) || cwd;
|
|
140979
|
+
if (taskAgent && legacySessionId && !agentSessions[taskAgent]) {
|
|
140980
|
+
agentSessions[taskAgent] = { sessionId: legacySessionId, cwd: legacyCwd };
|
|
140981
|
+
}
|
|
140982
|
+
agentSessions[activeAgent] = { sessionId, cwd };
|
|
140983
|
+
nextPayload.activeAgent = activeAgent;
|
|
140984
|
+
nextPayload.agentSessions = agentSessions;
|
|
140985
|
+
}
|
|
140892
140986
|
if (task?.conversationKind !== "nativeSession") {
|
|
140893
140987
|
return nextPayload;
|
|
140894
140988
|
}
|
|
@@ -141001,10 +141095,44 @@ function forwardTaskOutputToLeader(log2, nodeRegistry, taskId, event) {
|
|
|
141001
141095
|
});
|
|
141002
141096
|
});
|
|
141003
141097
|
}
|
|
141098
|
+
function postLogsReadyToLeader(log2, leaderEndpoint, taskId, total) {
|
|
141099
|
+
fetch(`${leaderEndpoint}/api/worker/logs-ready`, applyRequestAuthHeaders({
|
|
141100
|
+
method: "POST",
|
|
141101
|
+
headers: { "Content-Type": "application/json" },
|
|
141102
|
+
body: JSON.stringify({ taskId, total })
|
|
141103
|
+
})).then((response) => {
|
|
141104
|
+
if (!response.ok) {
|
|
141105
|
+
log2.warn("leader rejected log readiness report", {
|
|
141106
|
+
taskId,
|
|
141107
|
+
total,
|
|
141108
|
+
leaderEndpoint,
|
|
141109
|
+
statusCode: response.status
|
|
141110
|
+
});
|
|
141111
|
+
return;
|
|
141112
|
+
}
|
|
141113
|
+
log2.debug("forwarded log readiness to leader", { taskId, total, leaderEndpoint, statusCode: response.status });
|
|
141114
|
+
}).catch((err) => {
|
|
141115
|
+
log2.warn("failed to forward log readiness", {
|
|
141116
|
+
taskId,
|
|
141117
|
+
total,
|
|
141118
|
+
leaderEndpoint,
|
|
141119
|
+
error: err instanceof Error ? err.message : String(err)
|
|
141120
|
+
});
|
|
141121
|
+
});
|
|
141122
|
+
}
|
|
141123
|
+
function forwardTaskLogsReadyToLeader(log2, nodeRegistry, taskId, total) {
|
|
141124
|
+
const leaderEndpoint = nodeRegistry.getLeaderEndpoint();
|
|
141125
|
+
if (!leaderEndpoint) {
|
|
141126
|
+
log2.warn("skipping log readiness forward because leader endpoint is missing", { taskId, total });
|
|
141127
|
+
return;
|
|
141128
|
+
}
|
|
141129
|
+
postLogsReadyToLeader(log2, leaderEndpoint, taskId, total);
|
|
141130
|
+
}
|
|
141004
141131
|
function registerLeaderForwarding(eventBus, nodeRegistry, log2, taskId, agent, reporter) {
|
|
141005
141132
|
const cleanup = () => {
|
|
141006
141133
|
eventBus.off("task.status", onTaskStatus);
|
|
141007
141134
|
eventBus.off("task.output", onTaskOutput);
|
|
141135
|
+
eventBus.off("task.logs.ready", onTaskLogsReady);
|
|
141008
141136
|
};
|
|
141009
141137
|
const onTaskOutput = (data) => {
|
|
141010
141138
|
if (data.taskId !== taskId) return;
|
|
@@ -141016,6 +141144,16 @@ function registerLeaderForwarding(eventBus, nodeRegistry, log2, taskId, agent, r
|
|
|
141016
141144
|
if (reporter) reporter.reportOutput(taskId, data.event);
|
|
141017
141145
|
else forwardTaskOutputToLeader(log2, nodeRegistry, taskId, data.event);
|
|
141018
141146
|
};
|
|
141147
|
+
const onTaskLogsReady = (data) => {
|
|
141148
|
+
if (data.taskId !== taskId) return;
|
|
141149
|
+
log2.debug("task.logs.ready event", {
|
|
141150
|
+
taskId,
|
|
141151
|
+
total: data.total,
|
|
141152
|
+
hasLeader: !!nodeRegistry.getLeaderEndpoint()
|
|
141153
|
+
});
|
|
141154
|
+
if (reporter) reporter.reportLogsReady(taskId, data.total);
|
|
141155
|
+
else forwardTaskLogsReadyToLeader(log2, nodeRegistry, taskId, data.total);
|
|
141156
|
+
};
|
|
141019
141157
|
const onTaskStatus = (data) => {
|
|
141020
141158
|
if (data.taskId !== taskId || data.status === "running") return;
|
|
141021
141159
|
cleanup();
|
|
@@ -141041,11 +141179,175 @@ function registerLeaderForwarding(eventBus, nodeRegistry, log2, taskId, agent, r
|
|
|
141041
141179
|
});
|
|
141042
141180
|
};
|
|
141043
141181
|
eventBus.on("task.output", onTaskOutput);
|
|
141182
|
+
eventBus.on("task.logs.ready", onTaskLogsReady);
|
|
141044
141183
|
eventBus.on("task.status", onTaskStatus);
|
|
141045
141184
|
log2.debug("registered leader forwarding listeners", { taskId, agent });
|
|
141046
141185
|
return cleanup;
|
|
141047
141186
|
}
|
|
141048
141187
|
|
|
141188
|
+
// ../../packages/core/src/tasks/agent-task-turn.ts
|
|
141189
|
+
init_cjs_shims();
|
|
141190
|
+
function startAgentTaskTurn(options) {
|
|
141191
|
+
const agent = resolveActiveAgent(options.task, options.targetAgent);
|
|
141192
|
+
if (!supportsFollowUpAgent(agent)) {
|
|
141193
|
+
throw new MeshyError("VALIDATION_ERROR", `Agent ${agent} does not support chat messages`, 400);
|
|
141194
|
+
}
|
|
141195
|
+
const engine = options.engineRegistry.get(agent);
|
|
141196
|
+
if (!engine) {
|
|
141197
|
+
throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${agent}`, 400);
|
|
141198
|
+
}
|
|
141199
|
+
const updates = {
|
|
141200
|
+
status: "running",
|
|
141201
|
+
assignedTo: options.assignedTo
|
|
141202
|
+
};
|
|
141203
|
+
if (options.targetAgent || options.task.payload.activeAgent !== void 0) {
|
|
141204
|
+
updates.payload = {
|
|
141205
|
+
...options.task.payload,
|
|
141206
|
+
activeAgent: agent
|
|
141207
|
+
};
|
|
141208
|
+
}
|
|
141209
|
+
options.taskEngine.updateTask(options.task.id, updates);
|
|
141210
|
+
const handoffEvent = buildExplicitHandoffEvent(options.task, options.targetAgent, agent);
|
|
141211
|
+
if (handoffEvent) {
|
|
141212
|
+
recordAndEmit(options, engine, handoffEvent);
|
|
141213
|
+
}
|
|
141214
|
+
const handoffContent = handoffEvent ? buildAgentHandoffContent(options.task, engine, options.content, agent) : null;
|
|
141215
|
+
const sendContent = handoffContent ?? options.content;
|
|
141216
|
+
const sendOptions = handoffContent ? { logContent: options.content } : void 0;
|
|
141217
|
+
try {
|
|
141218
|
+
if (sendOptions) engine.sendMessage(options.task.id, sendContent, sendOptions);
|
|
141219
|
+
else engine.sendMessage(options.task.id, sendContent);
|
|
141220
|
+
return;
|
|
141221
|
+
} catch (err) {
|
|
141222
|
+
if (!shouldStartHandoff(options.targetAgent, err)) {
|
|
141223
|
+
throw err;
|
|
141224
|
+
}
|
|
141225
|
+
options.logger.info("starting cross-agent handoff turn", {
|
|
141226
|
+
taskId: options.task.id,
|
|
141227
|
+
fromAgent: resolveActiveAgent(options.task),
|
|
141228
|
+
toAgent: agent,
|
|
141229
|
+
...options.metadata
|
|
141230
|
+
});
|
|
141231
|
+
startHandoffRun(options, engine, agent, !handoffEvent, handoffContent);
|
|
141232
|
+
}
|
|
141233
|
+
}
|
|
141234
|
+
function resolveActiveAgent(task, targetAgent) {
|
|
141235
|
+
const explicit = targetAgent?.trim();
|
|
141236
|
+
if (explicit) return explicit;
|
|
141237
|
+
const active = typeof task.payload.activeAgent === "string" ? task.payload.activeAgent.trim() : "";
|
|
141238
|
+
return active || task.agent;
|
|
141239
|
+
}
|
|
141240
|
+
function shouldStartHandoff(targetAgent, err) {
|
|
141241
|
+
return Boolean(targetAgent) && err instanceof MeshyError && err.code === "TASK_NOT_FOUND";
|
|
141242
|
+
}
|
|
141243
|
+
function buildExplicitHandoffEvent(task, targetAgent, agent) {
|
|
141244
|
+
if (!targetAgent?.trim()) return null;
|
|
141245
|
+
const fromAgent = resolveActiveAgent(task);
|
|
141246
|
+
return fromAgent === agent ? null : buildAgentHandoffLogEvent(fromAgent, agent);
|
|
141247
|
+
}
|
|
141248
|
+
function startHandoffRun(options, engine, agent, recordBoundary, prebuiltContent) {
|
|
141249
|
+
const fromAgent = resolveActiveAgent(options.task);
|
|
141250
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
141251
|
+
const boundary = buildAgentHandoffLogEvent(fromAgent, agent, timestamp);
|
|
141252
|
+
const userEvent = {
|
|
141253
|
+
...buildTaskUserLogEvent(options.content, timestamp),
|
|
141254
|
+
agent
|
|
141255
|
+
};
|
|
141256
|
+
if (recordBoundary) {
|
|
141257
|
+
recordAndEmit(options, engine, boundary);
|
|
141258
|
+
}
|
|
141259
|
+
recordAndEmit(options, engine, userEvent);
|
|
141260
|
+
const handoffTask = {
|
|
141261
|
+
...options.task,
|
|
141262
|
+
agent,
|
|
141263
|
+
status: "running",
|
|
141264
|
+
assignedTo: options.assignedTo,
|
|
141265
|
+
payload: {
|
|
141266
|
+
...options.task.payload,
|
|
141267
|
+
activeAgent: agent,
|
|
141268
|
+
initialMessage: prebuiltContent ?? buildAgentHandoffContent(options.task, engine, options.content, agent)
|
|
141269
|
+
}
|
|
141270
|
+
};
|
|
141271
|
+
engine.run(handoffTask);
|
|
141272
|
+
}
|
|
141273
|
+
function recordAndEmit(options, engine, event) {
|
|
141274
|
+
engine.recordOutput(options.task.id, event);
|
|
141275
|
+
options.eventBus.emit("task.output", { taskId: options.task.id, event });
|
|
141276
|
+
}
|
|
141277
|
+
function buildAgentHandoffLogEvent(fromAgent, toAgent, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
141278
|
+
return {
|
|
141279
|
+
type: "agent.handoff",
|
|
141280
|
+
fromAgent,
|
|
141281
|
+
toAgent,
|
|
141282
|
+
timestamp
|
|
141283
|
+
};
|
|
141284
|
+
}
|
|
141285
|
+
function buildAgentHandoffContent(task, engine, currentContent, targetAgent) {
|
|
141286
|
+
const logs4 = readTaskLogs(engine, task.id);
|
|
141287
|
+
const historyLines = extractVisibleTranscriptLines(logs4);
|
|
141288
|
+
if (historyLines.length === 0) {
|
|
141289
|
+
const initialLines = contentToVisibleLines("User", normalizeTaskUserMessageContent(task.payload.initialMessage));
|
|
141290
|
+
historyLines.push(...initialLines);
|
|
141291
|
+
}
|
|
141292
|
+
const currentText = contentToPlainText(currentContent) || "[non-text user content]";
|
|
141293
|
+
const text10 = [
|
|
141294
|
+
`You are taking over this Meshy task as ${targetAgent}.`,
|
|
141295
|
+
"",
|
|
141296
|
+
"Previous visible conversation:",
|
|
141297
|
+
historyLines.length > 0 ? historyLines.join("\n") : "[No visible previous transcript found.]",
|
|
141298
|
+
"",
|
|
141299
|
+
"Current user request:",
|
|
141300
|
+
currentText
|
|
141301
|
+
].join("\n");
|
|
141302
|
+
return [{ type: "text", text: text10 }, ...currentContent.filter((part) => part.type !== "text")];
|
|
141303
|
+
}
|
|
141304
|
+
function readTaskLogs(engine, taskId) {
|
|
141305
|
+
return readJsonLines(engine.getLogPath(taskId));
|
|
141306
|
+
}
|
|
141307
|
+
function extractVisibleTranscriptLines(events) {
|
|
141308
|
+
const lines = [];
|
|
141309
|
+
for (const event of events) {
|
|
141310
|
+
if (event.type === "user" && event.isMeta !== true && event.isSidechain !== true) {
|
|
141311
|
+
lines.push(...contentToVisibleLines("User", extractUserContent(event)));
|
|
141312
|
+
}
|
|
141313
|
+
if (event.type === "assistant") {
|
|
141314
|
+
const text10 = extractAssistantText(event);
|
|
141315
|
+
if (text10) lines.push(`Assistant: ${text10}`);
|
|
141316
|
+
}
|
|
141317
|
+
}
|
|
141318
|
+
return lines;
|
|
141319
|
+
}
|
|
141320
|
+
function extractUserContent(event) {
|
|
141321
|
+
const message = isRecord6(event.message) ? event.message : null;
|
|
141322
|
+
const messageContent = message?.content;
|
|
141323
|
+
const directContent = event.content;
|
|
141324
|
+
return normalizeTaskUserMessageContent(messageContent ?? directContent ?? event.message).filter((part) => part.type !== "tool_result");
|
|
141325
|
+
}
|
|
141326
|
+
function contentToVisibleLines(label, content3) {
|
|
141327
|
+
const text10 = contentToPlainText(content3);
|
|
141328
|
+
return text10 ? [`${label}: ${text10}`] : [];
|
|
141329
|
+
}
|
|
141330
|
+
function contentToPlainText(content3) {
|
|
141331
|
+
return content3.map((part) => {
|
|
141332
|
+
if (part.type === "text") return part.text;
|
|
141333
|
+
if (part.type === "image") return `[image: ${part.filename ?? part.mediaType}]`;
|
|
141334
|
+
return "";
|
|
141335
|
+
}).filter(Boolean).join("\n").trim();
|
|
141336
|
+
}
|
|
141337
|
+
function extractAssistantText(event) {
|
|
141338
|
+
if (typeof event.message === "string") return event.message.trim();
|
|
141339
|
+
const content3 = isRecord6(event.message) ? event.message.content : event.content;
|
|
141340
|
+
if (!Array.isArray(content3)) return "";
|
|
141341
|
+
return content3.flatMap((block) => {
|
|
141342
|
+
if (!isRecord6(block) || block.type !== "text" || typeof block.text !== "string") return [];
|
|
141343
|
+
const text10 = block.text.trim();
|
|
141344
|
+
return text10 ? [text10] : [];
|
|
141345
|
+
}).join("\n").trim();
|
|
141346
|
+
}
|
|
141347
|
+
function isRecord6(value) {
|
|
141348
|
+
return typeof value === "object" && value !== null;
|
|
141349
|
+
}
|
|
141350
|
+
|
|
141049
141351
|
// ../../packages/core/src/tasks/leader-task-reporter.ts
|
|
141050
141352
|
init_cjs_shims();
|
|
141051
141353
|
var RestLeaderTaskReporter = class {
|
|
@@ -141089,6 +141391,14 @@ var RestLeaderTaskReporter = class {
|
|
|
141089
141391
|
});
|
|
141090
141392
|
});
|
|
141091
141393
|
}
|
|
141394
|
+
reportLogsReady(taskId, total) {
|
|
141395
|
+
const leaderEndpoint = this.nodeRegistry.getLeaderEndpoint();
|
|
141396
|
+
if (!leaderEndpoint) {
|
|
141397
|
+
this.logger.warn("skipping log readiness report because leader endpoint is missing", { taskId, total });
|
|
141398
|
+
return;
|
|
141399
|
+
}
|
|
141400
|
+
postLogsReadyToLeader(this.logger, leaderEndpoint, taskId, total);
|
|
141401
|
+
}
|
|
141092
141402
|
patchTask(taskId, data, label, successMessage) {
|
|
141093
141403
|
const leaderEndpoint = this.nodeRegistry.getLeaderEndpoint();
|
|
141094
141404
|
if (!leaderEndpoint) {
|
|
@@ -141540,14 +141850,14 @@ function getClaudeStreamError(event) {
|
|
|
141540
141850
|
}
|
|
141541
141851
|
return null;
|
|
141542
141852
|
}
|
|
141543
|
-
function
|
|
141853
|
+
function isRecord7(value) {
|
|
141544
141854
|
return typeof value === "object" && value !== null;
|
|
141545
141855
|
}
|
|
141546
141856
|
function getClaudeToolResultText(block) {
|
|
141547
141857
|
const content3 = block.content;
|
|
141548
141858
|
if (typeof content3 === "string") return content3;
|
|
141549
141859
|
if (Array.isArray(content3)) {
|
|
141550
|
-
return content3.filter(
|
|
141860
|
+
return content3.filter(isRecord7).map((entry) => String(entry.text ?? "")).join("\n");
|
|
141551
141861
|
}
|
|
141552
141862
|
return "";
|
|
141553
141863
|
}
|
|
@@ -141568,10 +141878,10 @@ function isEmptyClaudeMessageEvent(event) {
|
|
|
141568
141878
|
return false;
|
|
141569
141879
|
}
|
|
141570
141880
|
const message = event.message;
|
|
141571
|
-
if (!
|
|
141881
|
+
if (!isRecord7(message) || !Array.isArray(message.content)) {
|
|
141572
141882
|
return false;
|
|
141573
141883
|
}
|
|
141574
|
-
return !message.content.filter(
|
|
141884
|
+
return !message.content.filter(isRecord7).some(hasVisibleClaudeContentBlock);
|
|
141575
141885
|
}
|
|
141576
141886
|
function shouldSkipClaudeTranscriptEvent(event) {
|
|
141577
141887
|
return event.isMeta === true || event.isSidechain === true || event.type === "attachment" || event.type === "last-prompt" || isEmptyClaudeMessageEvent(event);
|
|
@@ -141585,13 +141895,13 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141585
141895
|
init() {
|
|
141586
141896
|
const { tasks } = this.taskEngine.listTasks();
|
|
141587
141897
|
for (const task of tasks) {
|
|
141588
|
-
|
|
141589
|
-
|
|
141590
|
-
|
|
141591
|
-
|
|
141592
|
-
|
|
141593
|
-
|
|
141594
|
-
|
|
141898
|
+
const session = getPersistedAgentSession(task, "claudecode");
|
|
141899
|
+
if (!session) continue;
|
|
141900
|
+
this.sessions.set(task.id, {
|
|
141901
|
+
sessionId: session.sessionId,
|
|
141902
|
+
cwd: path10.resolve(session.cwd || task.effectiveProjectPath || task.project || process.cwd()),
|
|
141903
|
+
title: task.title
|
|
141904
|
+
});
|
|
141595
141905
|
}
|
|
141596
141906
|
if (this.sessions.size > 0) {
|
|
141597
141907
|
this.logger.info("Recovered sessions from store", { count: this.sessions.size });
|
|
@@ -141647,7 +141957,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141647
141957
|
this.persistSession(task.id, event.session_id, cwd);
|
|
141648
141958
|
this.logger.info("Session established", { taskId: task.id, sessionId: event.session_id });
|
|
141649
141959
|
}
|
|
141650
|
-
const outputEvent = timestampClaudeTranscriptEvent(event);
|
|
141960
|
+
const outputEvent = event.type === "system" && event.subtype === "init" && typeof event.session_id === "string" ? { ...timestampClaudeTranscriptEvent(event), agent: "claudecode" } : timestampClaudeTranscriptEvent(event);
|
|
141651
141961
|
this.emitOutput(task.id, outputEvent);
|
|
141652
141962
|
this.appendLog(task.id, outputEvent);
|
|
141653
141963
|
} catch {
|
|
@@ -141664,7 +141974,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141664
141974
|
proc.stderr.on("data", (chunk) => {
|
|
141665
141975
|
stderrBuffer += chunk.toString();
|
|
141666
141976
|
});
|
|
141667
|
-
proc.on("close", (code4) => {
|
|
141977
|
+
proc.on("close", async (code4) => {
|
|
141668
141978
|
if (buffer.trim()) {
|
|
141669
141979
|
processLine(buffer);
|
|
141670
141980
|
}
|
|
@@ -141673,6 +141983,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141673
141983
|
return;
|
|
141674
141984
|
}
|
|
141675
141985
|
try {
|
|
141986
|
+
await this.flushLogsAndEmitReady(task.id);
|
|
141676
141987
|
if (code4 === 0 && !streamError) {
|
|
141677
141988
|
this.logger.info("Task completed successfully", { taskId: task.id, title: task.title });
|
|
141678
141989
|
this.taskEngine.reportResult(task.id, { message: `Task "${task.title}" completed` });
|
|
@@ -141710,7 +142021,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141710
142021
|
this.writeUserMessage(proc.stdin, initialContent);
|
|
141711
142022
|
proc.unref();
|
|
141712
142023
|
}
|
|
141713
|
-
sendMessage(taskId, content3) {
|
|
142024
|
+
sendMessage(taskId, content3, options) {
|
|
141714
142025
|
let session = this.sessions.get(taskId);
|
|
141715
142026
|
if (!session) {
|
|
141716
142027
|
const recovered = this.recoverSession(taskId);
|
|
@@ -141729,7 +142040,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141729
142040
|
if (!session) {
|
|
141730
142041
|
throw new MeshyError("TASK_NOT_FOUND", `No active session for task ${taskId}`, 404);
|
|
141731
142042
|
}
|
|
141732
|
-
const userEvent = buildTaskUserLogEvent(content3);
|
|
142043
|
+
const userEvent = buildTaskUserLogEvent(options?.logContent ?? content3);
|
|
141733
142044
|
this.appendLog(taskId, userEvent);
|
|
141734
142045
|
this.emitOutput(taskId, userEvent);
|
|
141735
142046
|
this.logger.info("Sending follow-up message", { taskId, sessionId: session.sessionId });
|
|
@@ -141776,7 +142087,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141776
142087
|
});
|
|
141777
142088
|
this.persistSession(taskId, event.session_id, session.cwd);
|
|
141778
142089
|
}
|
|
141779
|
-
const outputEvent = timestampClaudeTranscriptEvent(event);
|
|
142090
|
+
const outputEvent = event.type === "system" && event.subtype === "init" && typeof event.session_id === "string" ? { ...timestampClaudeTranscriptEvent(event), agent: "claudecode" } : timestampClaudeTranscriptEvent(event);
|
|
141780
142091
|
this.emitOutput(taskId, outputEvent);
|
|
141781
142092
|
this.appendLog(taskId, outputEvent);
|
|
141782
142093
|
} catch {
|
|
@@ -141793,7 +142104,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141793
142104
|
proc.stderr.on("data", (chunk) => {
|
|
141794
142105
|
stderrBuffer += chunk.toString();
|
|
141795
142106
|
});
|
|
141796
|
-
proc.on("close", (code4) => {
|
|
142107
|
+
proc.on("close", async (code4) => {
|
|
141797
142108
|
if (buffer.trim()) {
|
|
141798
142109
|
processLine(buffer);
|
|
141799
142110
|
}
|
|
@@ -141802,6 +142113,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141802
142113
|
return;
|
|
141803
142114
|
}
|
|
141804
142115
|
try {
|
|
142116
|
+
await this.flushLogsAndEmitReady(taskId);
|
|
141805
142117
|
if (code4 === 0 && !streamError) {
|
|
141806
142118
|
this.logger.info("Follow-up completed", { taskId, sessionId: session.sessionId });
|
|
141807
142119
|
this.taskEngine.reportResult(taskId, { message: `Task "${session.title}" completed` });
|
|
@@ -141854,7 +142166,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141854
142166
|
try {
|
|
141855
142167
|
const current = this.taskEngine.getTask(taskId);
|
|
141856
142168
|
this.taskEngine.updateTask(taskId, {
|
|
141857
|
-
payload: buildPersistedSessionPayload(current, sessionId, cwd)
|
|
142169
|
+
payload: buildPersistedSessionPayload(current, sessionId, cwd, "claudecode")
|
|
141858
142170
|
});
|
|
141859
142171
|
} catch {
|
|
141860
142172
|
}
|
|
@@ -141873,7 +142185,8 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141873
142185
|
const event = JSON.parse(line);
|
|
141874
142186
|
if (event.type === "system" && event.subtype === "init" && typeof event.session_id === "string") {
|
|
141875
142187
|
const task = this.taskEngine.getTask(taskId);
|
|
141876
|
-
|
|
142188
|
+
if (!canUseSessionLogEventForAgent(task, "claudecode", event)) continue;
|
|
142189
|
+
const persistedCwd = getPersistedAgentSession(task, "claudecode")?.cwd ?? (typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0);
|
|
141877
142190
|
return {
|
|
141878
142191
|
sessionId: event.session_id,
|
|
141879
142192
|
cwd: path10.resolve(
|
|
@@ -141889,14 +142202,12 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
|
|
|
141889
142202
|
}
|
|
141890
142203
|
recoverPersistedSession(taskId) {
|
|
141891
142204
|
const task = this.taskEngine.getTask(taskId);
|
|
141892
|
-
const
|
|
141893
|
-
if (!
|
|
141894
|
-
return null;
|
|
141895
|
-
}
|
|
142205
|
+
const persisted = getPersistedAgentSession(task, "claudecode");
|
|
142206
|
+
if (!persisted) return null;
|
|
141896
142207
|
return {
|
|
141897
|
-
sessionId,
|
|
142208
|
+
sessionId: persisted.sessionId,
|
|
141898
142209
|
cwd: path10.resolve(
|
|
141899
|
-
|
|
142210
|
+
persisted.cwd || task?.effectiveProjectPath || task?.project || process.cwd()
|
|
141900
142211
|
),
|
|
141901
142212
|
title: task?.title ?? taskId
|
|
141902
142213
|
};
|
|
@@ -141909,21 +142220,21 @@ var fs11 = __toESM(require("fs"), 1);
|
|
|
141909
142220
|
var path11 = __toESM(require("path"), 1);
|
|
141910
142221
|
var import_node_child_process5 = require("child_process");
|
|
141911
142222
|
var CODEX_SESSION_MIRROR_INTERVAL_MS = 500;
|
|
141912
|
-
function
|
|
142223
|
+
function isRecord8(value) {
|
|
141913
142224
|
return typeof value === "object" && value !== null;
|
|
141914
142225
|
}
|
|
141915
142226
|
function stableStringify(value) {
|
|
141916
142227
|
if (Array.isArray(value)) {
|
|
141917
142228
|
return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
|
|
141918
142229
|
}
|
|
141919
|
-
if (!
|
|
142230
|
+
if (!isRecord8(value)) {
|
|
141920
142231
|
return JSON.stringify(value);
|
|
141921
142232
|
}
|
|
141922
142233
|
return `{${Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)).map(([key2, entryValue]) => `${JSON.stringify(key2)}:${stableStringify(entryValue)}`).join(",")}}`;
|
|
141923
142234
|
}
|
|
141924
142235
|
function transcriptEventSignature(event) {
|
|
141925
142236
|
const message = event.message;
|
|
141926
|
-
if ((event.type === "assistant" || event.type === "user") &&
|
|
142237
|
+
if ((event.type === "assistant" || event.type === "user") && isRecord8(message) && Array.isArray(message.content)) {
|
|
141927
142238
|
return `${event.type}:${stableStringify(message.content)}`;
|
|
141928
142239
|
}
|
|
141929
142240
|
return stableStringify(event);
|
|
@@ -141962,9 +142273,6 @@ function splitPromptContent(content3) {
|
|
|
141962
142273
|
images
|
|
141963
142274
|
};
|
|
141964
142275
|
}
|
|
141965
|
-
function hasImageContent(content3) {
|
|
141966
|
-
return content3.some((part) => part.type === "image");
|
|
141967
|
-
}
|
|
141968
142276
|
function buildCodexModeArgs(mode) {
|
|
141969
142277
|
switch (mode) {
|
|
141970
142278
|
case "plan":
|
|
@@ -141987,13 +142295,13 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
141987
142295
|
init() {
|
|
141988
142296
|
const { tasks } = this.taskEngine.listTasks();
|
|
141989
142297
|
for (const task of tasks) {
|
|
141990
|
-
|
|
141991
|
-
|
|
141992
|
-
|
|
141993
|
-
|
|
141994
|
-
|
|
141995
|
-
|
|
141996
|
-
|
|
142298
|
+
const session = getPersistedAgentSession(task, "codex");
|
|
142299
|
+
if (!session) continue;
|
|
142300
|
+
this.sessions.set(task.id, {
|
|
142301
|
+
sessionId: session.sessionId,
|
|
142302
|
+
cwd: path11.resolve(session.cwd || task.effectiveProjectPath || task.project || process.cwd()),
|
|
142303
|
+
title: task.title
|
|
142304
|
+
});
|
|
141997
142305
|
}
|
|
141998
142306
|
if (this.sessions.size > 0) {
|
|
141999
142307
|
this.logger.info("Recovered Codex sessions from store", { count: this.sessions.size });
|
|
@@ -142004,7 +142312,7 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142004
142312
|
const cwd = task.effectiveProjectPath ?? task.project ?? process.cwd();
|
|
142005
142313
|
const initialContent = getTaskInitialMessageContent(task);
|
|
142006
142314
|
const { prompt, imagePaths, promptEcho } = this.prepareAssets(task.id, initialContent);
|
|
142007
|
-
this.markCodexPromptEchoEmitted(task.id, [promptEcho, prompt]
|
|
142315
|
+
this.markCodexPromptEchoEmitted(task.id, [promptEcho, prompt]);
|
|
142008
142316
|
const args = this.buildArgs(imagePaths, { model: config2.model, mode: config2.mode ?? "bypass" });
|
|
142009
142317
|
this.ensureLogDir();
|
|
142010
142318
|
this.logger.info("Spawning codex CLI", { taskId: task.id, title: task.title, cwd });
|
|
@@ -142017,7 +142325,7 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142017
142325
|
this.writePrompt(proc.stdin, prompt);
|
|
142018
142326
|
proc.unref();
|
|
142019
142327
|
}
|
|
142020
|
-
sendMessage(taskId, content3) {
|
|
142328
|
+
sendMessage(taskId, content3, options) {
|
|
142021
142329
|
let session = this.sessions.get(taskId);
|
|
142022
142330
|
if (!session) {
|
|
142023
142331
|
const recovered = this.recoverSession(taskId);
|
|
@@ -142039,12 +142347,12 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142039
142347
|
const current = this.taskEngine.getTask(taskId);
|
|
142040
142348
|
const model = typeof current?.payload.model === "string" ? current.payload.model : void 0;
|
|
142041
142349
|
const mode = current?.payload.mode;
|
|
142042
|
-
const userEvent = buildTaskUserLogEvent(content3);
|
|
142350
|
+
const userEvent = buildTaskUserLogEvent(options?.logContent ?? content3);
|
|
142043
142351
|
this.markTranscriptEventEmitted(taskId, userEvent);
|
|
142044
142352
|
this.appendLog(taskId, userEvent);
|
|
142045
142353
|
this.emitOutput(taskId, userEvent);
|
|
142046
142354
|
const { prompt, imagePaths, promptEcho } = this.prepareAssets(taskId, content3);
|
|
142047
|
-
this.markCodexPromptEchoEmitted(taskId, [promptEcho, prompt]
|
|
142355
|
+
this.markCodexPromptEchoEmitted(taskId, [promptEcho, prompt]);
|
|
142048
142356
|
const args = this.buildArgs(imagePaths, {
|
|
142049
142357
|
model,
|
|
142050
142358
|
sessionId: session.sessionId,
|
|
@@ -142103,7 +142411,7 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142103
142411
|
proc.stderr?.on("data", (chunk) => {
|
|
142104
142412
|
stderrBuffer += chunk.toString();
|
|
142105
142413
|
});
|
|
142106
|
-
proc.on("close", (code4) => {
|
|
142414
|
+
proc.on("close", async (code4) => {
|
|
142107
142415
|
if (buffer.trim()) {
|
|
142108
142416
|
processLine(buffer);
|
|
142109
142417
|
}
|
|
@@ -142116,6 +142424,7 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142116
142424
|
try {
|
|
142117
142425
|
this.flushNativeSessionMirror(taskId);
|
|
142118
142426
|
this.flushPendingAmbiguousAssistantTextEvents(taskId);
|
|
142427
|
+
await this.flushLogsAndEmitReady(taskId);
|
|
142119
142428
|
if (code4 === 0) {
|
|
142120
142429
|
this.logger.info(isFollowUp ? "Codex follow-up completed" : "Codex task completed successfully", {
|
|
142121
142430
|
taskId,
|
|
@@ -142262,8 +142571,7 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142262
142571
|
markTranscriptEventEmitted(taskId, event) {
|
|
142263
142572
|
this.getEmittedTranscriptSignatures(taskId).add(transcriptEventSignature(event));
|
|
142264
142573
|
}
|
|
142265
|
-
markCodexPromptEchoEmitted(taskId, prompts
|
|
142266
|
-
if (!hasImages) return;
|
|
142574
|
+
markCodexPromptEchoEmitted(taskId, prompts) {
|
|
142267
142575
|
for (const prompt of new Set(prompts.map((candidate) => candidate.trim()).filter(Boolean))) {
|
|
142268
142576
|
this.markTranscriptEventEmitted(taskId, buildTaskUserLogEvent([{ type: "text", text: prompt }]));
|
|
142269
142577
|
}
|
|
@@ -142302,8 +142610,9 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142302
142610
|
title
|
|
142303
142611
|
});
|
|
142304
142612
|
this.persistSession(taskId, event.thread_id, cwd);
|
|
142305
|
-
|
|
142306
|
-
this.
|
|
142613
|
+
const sessionEvent = { ...event, agent: "codex" };
|
|
142614
|
+
this.appendLog(taskId, sessionEvent);
|
|
142615
|
+
this.emitOutput(taskId, sessionEvent);
|
|
142307
142616
|
this.startNativeSessionMirror(taskId, event.thread_id);
|
|
142308
142617
|
this.logger.info("Codex session established", { taskId, sessionId: event.thread_id });
|
|
142309
142618
|
return [];
|
|
@@ -142348,7 +142657,7 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142348
142657
|
try {
|
|
142349
142658
|
const current = this.taskEngine.getTask(taskId);
|
|
142350
142659
|
this.taskEngine.updateTask(taskId, {
|
|
142351
|
-
payload: buildPersistedSessionPayload(current, sessionId, cwd)
|
|
142660
|
+
payload: buildPersistedSessionPayload(current, sessionId, cwd, "codex")
|
|
142352
142661
|
});
|
|
142353
142662
|
} catch {
|
|
142354
142663
|
}
|
|
@@ -142367,7 +142676,8 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142367
142676
|
const event = JSON.parse(line);
|
|
142368
142677
|
if (event.type === "thread.started" && typeof event.thread_id === "string") {
|
|
142369
142678
|
const task = this.taskEngine.getTask(taskId);
|
|
142370
|
-
|
|
142679
|
+
if (!canUseSessionLogEventForAgent(task, "codex", event)) continue;
|
|
142680
|
+
const persistedCwd = getPersistedAgentSession(task, "codex")?.cwd ?? (typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0);
|
|
142371
142681
|
return {
|
|
142372
142682
|
sessionId: event.thread_id,
|
|
142373
142683
|
cwd: path11.resolve(persistedCwd ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()),
|
|
@@ -142381,14 +142691,12 @@ var CodexEngine = class extends ExecutionEngine {
|
|
|
142381
142691
|
}
|
|
142382
142692
|
recoverPersistedSession(taskId) {
|
|
142383
142693
|
const task = this.taskEngine.getTask(taskId);
|
|
142384
|
-
const
|
|
142385
|
-
if (!
|
|
142386
|
-
return null;
|
|
142387
|
-
}
|
|
142694
|
+
const persisted = getPersistedAgentSession(task, "codex");
|
|
142695
|
+
if (!persisted) return null;
|
|
142388
142696
|
return {
|
|
142389
|
-
sessionId,
|
|
142697
|
+
sessionId: persisted.sessionId,
|
|
142390
142698
|
cwd: path11.resolve(
|
|
142391
|
-
|
|
142699
|
+
persisted.cwd || task?.effectiveProjectPath || task?.project || process.cwd()
|
|
142392
142700
|
),
|
|
142393
142701
|
title: task?.title ?? taskId
|
|
142394
142702
|
};
|
|
@@ -142400,7 +142708,7 @@ init_cjs_shims();
|
|
|
142400
142708
|
var fs12 = __toESM(require("fs"), 1);
|
|
142401
142709
|
var path12 = __toESM(require("path"), 1);
|
|
142402
142710
|
var import_node_child_process6 = require("child_process");
|
|
142403
|
-
function
|
|
142711
|
+
function isRecord9(value) {
|
|
142404
142712
|
return typeof value === "object" && value !== null;
|
|
142405
142713
|
}
|
|
142406
142714
|
function contentToPrompt(content3) {
|
|
@@ -142438,7 +142746,7 @@ function inferExtension2(mediaType) {
|
|
|
142438
142746
|
return normalized.replace(/[^a-z0-9]/g, "") || "bin";
|
|
142439
142747
|
}
|
|
142440
142748
|
function extractSessionId(event) {
|
|
142441
|
-
const data =
|
|
142749
|
+
const data = isRecord9(event.data) ? event.data : void 0;
|
|
142442
142750
|
const direct = event.session_id ?? event.sessionId ?? event.conversation_id ?? event.conversationId ?? data?.sessionId ?? data?.session_id ?? data?.conversationId ?? data?.conversation_id;
|
|
142443
142751
|
if (typeof direct === "string" && direct.trim()) return direct.trim();
|
|
142444
142752
|
const type = typeof event.type === "string" ? event.type.toLowerCase() : "";
|
|
@@ -142452,13 +142760,13 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142452
142760
|
init() {
|
|
142453
142761
|
const { tasks } = this.taskEngine.listTasks();
|
|
142454
142762
|
for (const task of tasks) {
|
|
142455
|
-
|
|
142456
|
-
|
|
142457
|
-
|
|
142458
|
-
|
|
142459
|
-
|
|
142460
|
-
|
|
142461
|
-
|
|
142763
|
+
const session = getPersistedAgentSession(task, "copilot");
|
|
142764
|
+
if (!session) continue;
|
|
142765
|
+
this.sessions.set(task.id, {
|
|
142766
|
+
sessionId: session.sessionId,
|
|
142767
|
+
cwd: path12.resolve(session.cwd || task.effectiveProjectPath || task.project || process.cwd()),
|
|
142768
|
+
title: task.title
|
|
142769
|
+
});
|
|
142462
142770
|
}
|
|
142463
142771
|
if (this.sessions.size > 0) {
|
|
142464
142772
|
this.logger.info("Recovered Copilot CLI sessions from store", { count: this.sessions.size });
|
|
@@ -142487,7 +142795,7 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142487
142795
|
this.attachProcess(task.id, task.title, cwd, proc, false);
|
|
142488
142796
|
proc.unref();
|
|
142489
142797
|
}
|
|
142490
|
-
sendMessage(taskId, content3) {
|
|
142798
|
+
sendMessage(taskId, content3, options) {
|
|
142491
142799
|
let session = this.sessions.get(taskId);
|
|
142492
142800
|
if (!session) {
|
|
142493
142801
|
const recovered = this.recoverSession(taskId) ?? this.recoverPersistedSession(taskId);
|
|
@@ -142504,7 +142812,7 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142504
142812
|
const mode = current?.payload.mode;
|
|
142505
142813
|
const systemPrompt = typeof current?.payload.systemPrompt === "string" ? current.payload.systemPrompt : void 0;
|
|
142506
142814
|
const allowedTools = Array.isArray(current?.payload.allowedTools) && current.payload.allowedTools.every((tool) => typeof tool === "string") ? current.payload.allowedTools : void 0;
|
|
142507
|
-
const userEvent = buildTaskUserLogEvent(content3);
|
|
142815
|
+
const userEvent = buildTaskUserLogEvent(options?.logContent ?? content3);
|
|
142508
142816
|
this.appendLog(taskId, userEvent);
|
|
142509
142817
|
this.emitOutput(taskId, userEvent);
|
|
142510
142818
|
const prompt = buildPrompt(content3, systemPrompt);
|
|
@@ -142597,7 +142905,7 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142597
142905
|
proc.stderr?.on("data", (chunk) => {
|
|
142598
142906
|
stderrBuffer += chunk.toString();
|
|
142599
142907
|
});
|
|
142600
|
-
proc.on("close", (code4) => {
|
|
142908
|
+
proc.on("close", async (code4) => {
|
|
142601
142909
|
if (buffer.trim()) {
|
|
142602
142910
|
processLine(buffer);
|
|
142603
142911
|
}
|
|
@@ -142606,6 +142914,7 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142606
142914
|
return;
|
|
142607
142915
|
}
|
|
142608
142916
|
try {
|
|
142917
|
+
await this.flushLogsAndEmitReady(taskId);
|
|
142609
142918
|
if (code4 === 0) {
|
|
142610
142919
|
this.logger.info(isFollowUp ? "Copilot CLI follow-up completed" : "Copilot CLI task completed successfully", {
|
|
142611
142920
|
taskId,
|
|
@@ -142657,8 +142966,9 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142657
142966
|
if (sessionId) {
|
|
142658
142967
|
this.sessions.set(taskId, { sessionId, cwd, title });
|
|
142659
142968
|
this.persistSession(taskId, sessionId, cwd);
|
|
142660
|
-
|
|
142661
|
-
this.
|
|
142969
|
+
const sessionEvent = { ...event, agent: "copilot" };
|
|
142970
|
+
this.appendLog(taskId, sessionEvent);
|
|
142971
|
+
this.emitOutput(taskId, sessionEvent);
|
|
142662
142972
|
this.logger.info("Copilot CLI session established", { taskId, sessionId });
|
|
142663
142973
|
return [];
|
|
142664
142974
|
}
|
|
@@ -142668,7 +142978,7 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142668
142978
|
try {
|
|
142669
142979
|
const current = this.taskEngine.getTask(taskId);
|
|
142670
142980
|
this.taskEngine.updateTask(taskId, {
|
|
142671
|
-
payload: buildPersistedSessionPayload(current, sessionId, cwd)
|
|
142981
|
+
payload: buildPersistedSessionPayload(current, sessionId, cwd, "copilot")
|
|
142672
142982
|
});
|
|
142673
142983
|
} catch {
|
|
142674
142984
|
}
|
|
@@ -142687,7 +142997,8 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142687
142997
|
const sessionId = extractSessionId(event);
|
|
142688
142998
|
if (sessionId) {
|
|
142689
142999
|
const task = this.taskEngine.getTask(taskId);
|
|
142690
|
-
|
|
143000
|
+
if (!canUseSessionLogEventForAgent(task, "copilot", event)) continue;
|
|
143001
|
+
const persistedCwd = getPersistedAgentSession(task, "copilot")?.cwd ?? (typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0);
|
|
142691
143002
|
return {
|
|
142692
143003
|
sessionId,
|
|
142693
143004
|
cwd: path12.resolve(persistedCwd ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()),
|
|
@@ -142701,12 +143012,12 @@ var CopilotCliEngine = class extends ExecutionEngine {
|
|
|
142701
143012
|
}
|
|
142702
143013
|
recoverPersistedSession(taskId) {
|
|
142703
143014
|
const task = this.taskEngine.getTask(taskId);
|
|
142704
|
-
const
|
|
142705
|
-
if (!
|
|
143015
|
+
const persisted = getPersistedAgentSession(task, "copilot");
|
|
143016
|
+
if (!persisted) return null;
|
|
142706
143017
|
return {
|
|
142707
|
-
sessionId,
|
|
143018
|
+
sessionId: persisted.sessionId,
|
|
142708
143019
|
cwd: path12.resolve(
|
|
142709
|
-
|
|
143020
|
+
persisted.cwd || task?.effectiveProjectPath || task?.project || process.cwd()
|
|
142710
143021
|
),
|
|
142711
143022
|
title: task?.title ?? taskId
|
|
142712
143023
|
};
|
|
@@ -144136,22 +144447,33 @@ async function handleLocalNodeMessage(deps, message) {
|
|
|
144136
144447
|
const payload = message.payload;
|
|
144137
144448
|
if (!payload.taskId || !payload.content) return;
|
|
144138
144449
|
const task = deps.taskEngine.getTask(payload.taskId);
|
|
144139
|
-
const
|
|
144140
|
-
|
|
144141
|
-
|
|
144450
|
+
const agent = task ? resolveActiveAgent(task, payload.targetAgent) : void 0;
|
|
144451
|
+
const engine = agent ? deps.engineRegistry.get(agent) : void 0;
|
|
144452
|
+
if (!task || !agent || !engine) return;
|
|
144142
144453
|
if (!deps.nodeRegistry.isLeader()) {
|
|
144143
144454
|
const reporter = new RestLeaderTaskReporter(deps.nodeRegistry, log2);
|
|
144144
144455
|
reporter.reportRunning(payload.taskId, { branch: task.branch });
|
|
144145
|
-
registerLeaderForwarding(deps.eventBus, deps.nodeRegistry, log2, payload.taskId,
|
|
144456
|
+
registerLeaderForwarding(deps.eventBus, deps.nodeRegistry, log2, payload.taskId, agent, reporter);
|
|
144146
144457
|
}
|
|
144147
144458
|
try {
|
|
144148
|
-
|
|
144149
|
-
|
|
144459
|
+
startAgentTaskTurn({
|
|
144460
|
+
task,
|
|
144461
|
+
content: payload.content,
|
|
144462
|
+
targetAgent: payload.targetAgent,
|
|
144463
|
+
assignedTo: task.assignedTo,
|
|
144464
|
+
taskEngine: deps.taskEngine,
|
|
144465
|
+
engineRegistry: deps.engineRegistry,
|
|
144466
|
+
eventBus: deps.eventBus,
|
|
144467
|
+
logger: log2
|
|
144468
|
+
});
|
|
144469
|
+
log2.info("started keepalive-delivered follow-up execution", { taskId: payload.taskId, agent });
|
|
144150
144470
|
} catch (error2) {
|
|
144151
|
-
|
|
144471
|
+
const messageText = error2 instanceof Error ? error2.message : String(error2);
|
|
144472
|
+
log2.error("failed to start keepalive-delivered follow-up execution", {
|
|
144152
144473
|
taskId: payload.taskId,
|
|
144153
|
-
error:
|
|
144474
|
+
error: messageText
|
|
144154
144475
|
});
|
|
144476
|
+
deps.taskEngine.reportFailure(payload.taskId, `Engine follow-up failed before execution started: ${messageText}`);
|
|
144155
144477
|
}
|
|
144156
144478
|
return;
|
|
144157
144479
|
}
|
|
@@ -145366,6 +145688,7 @@ var SystemAgentInfoSchema = external_exports.object({
|
|
|
145366
145688
|
detail: external_exports.string().nullable().optional()
|
|
145367
145689
|
}).optional()
|
|
145368
145690
|
});
|
|
145691
|
+
var DefaultTaskAgentSchema = external_exports.enum(["codex", "claudecode", "copilot"]);
|
|
145369
145692
|
var SystemRuntimeUpdateInfoSchema = external_exports.object({
|
|
145370
145693
|
packageName: external_exports.string(),
|
|
145371
145694
|
currentVersion: external_exports.string().nullable(),
|
|
@@ -145380,6 +145703,7 @@ var NodeSettingsSnapshotSchema = external_exports.object({
|
|
|
145380
145703
|
version: external_exports.string(),
|
|
145381
145704
|
packageName: external_exports.string().optional(),
|
|
145382
145705
|
uptime: external_exports.number(),
|
|
145706
|
+
defaultTaskAgent: DefaultTaskAgentSchema.optional(),
|
|
145383
145707
|
auth: SystemAuthInfoSchema.optional(),
|
|
145384
145708
|
os: SystemOsInfoSchema.optional(),
|
|
145385
145709
|
runtime: SystemRuntimeInfoSchema.optional(),
|
|
@@ -145721,6 +146045,10 @@ var QuickChatsResponse = external_exports.object({
|
|
|
145721
146045
|
var ReplaceQuickChatsBody = external_exports.object({
|
|
145722
146046
|
quickChats: external_exports.array(QuickChatItem).max(100)
|
|
145723
146047
|
});
|
|
146048
|
+
var DefaultTaskAgentResponse = external_exports.object({
|
|
146049
|
+
defaultTaskAgent: DefaultTaskAgentSchema
|
|
146050
|
+
});
|
|
146051
|
+
var UpdateDefaultTaskAgentBody = DefaultTaskAgentResponse;
|
|
145724
146052
|
|
|
145725
146053
|
// ../../packages/api/src/schemas/tasks.ts
|
|
145726
146054
|
init_cjs_shims();
|
|
@@ -145772,6 +146100,7 @@ var TaskListResponse = external_exports.object({
|
|
|
145772
146100
|
queuedMessages: external_exports.array(external_exports.object({
|
|
145773
146101
|
id: external_exports.string(),
|
|
145774
146102
|
content: external_exports.array(external_exports.record(external_exports.unknown())).min(1),
|
|
146103
|
+
targetAgent: external_exports.enum(NATIVE_SESSION_AGENT_OPTIONS).optional(),
|
|
145775
146104
|
createdAt: external_exports.number()
|
|
145776
146105
|
})).optional(),
|
|
145777
146106
|
status: external_exports.enum(["pending", "assigned", "running", "completed", "failed", "cancelled", "archived"]),
|
|
@@ -145838,12 +146167,15 @@ var TaskMessageContentPart = external_exports.union([
|
|
|
145838
146167
|
var TaskMessageContent = external_exports.array(TaskMessageContentPart).min(1);
|
|
145839
146168
|
var SendMessageBody = external_exports.union([
|
|
145840
146169
|
external_exports.object({
|
|
145841
|
-
content: TaskMessageContent
|
|
146170
|
+
content: TaskMessageContent,
|
|
146171
|
+
targetAgent: external_exports.enum(NATIVE_SESSION_AGENT_OPTIONS).optional()
|
|
145842
146172
|
}),
|
|
145843
146173
|
external_exports.object({
|
|
145844
|
-
message: external_exports.string().trim().min(1)
|
|
146174
|
+
message: external_exports.string().trim().min(1),
|
|
146175
|
+
targetAgent: external_exports.enum(NATIVE_SESSION_AGENT_OPTIONS).optional()
|
|
145845
146176
|
}).transform((value) => ({
|
|
145846
|
-
content: [{ type: "text", text: value.message }]
|
|
146177
|
+
content: [{ type: "text", text: value.message }],
|
|
146178
|
+
...value.targetAgent ? { targetAgent: value.targetAgent } : {}
|
|
145847
146179
|
}))
|
|
145848
146180
|
]);
|
|
145849
146181
|
var AttachNativeSessionBody = external_exports.object({
|
|
@@ -145860,7 +146192,8 @@ var WorkerImportTaskBody = external_exports.object({
|
|
|
145860
146192
|
logs: external_exports.array(TaskLogEvent).default([])
|
|
145861
146193
|
});
|
|
145862
146194
|
var TaskLogsQuery = external_exports.object({
|
|
145863
|
-
after: external_exports.coerce.number().int().min(0).optional()
|
|
146195
|
+
after: external_exports.coerce.number().int().min(0).optional(),
|
|
146196
|
+
minTotal: external_exports.coerce.number().int().min(0).optional()
|
|
145864
146197
|
});
|
|
145865
146198
|
var CreateTaskShareBody = external_exports.object({
|
|
145866
146199
|
tenant: external_exports.string().trim().min(1).max(128).default(DEFAULT_TASK_SHARE_TENANT),
|
|
@@ -146282,6 +146615,7 @@ function durationMs(startedAt) {
|
|
|
146282
146615
|
}
|
|
146283
146616
|
function createRequestLoggingMiddleware(rootLogger, options = {}) {
|
|
146284
146617
|
const log2 = rootLogger.child("api/request");
|
|
146618
|
+
const lastLoggedAt = /* @__PURE__ */ new Map();
|
|
146285
146619
|
return (req, res, next2) => {
|
|
146286
146620
|
if (options.shouldLog && !options.shouldLog(req)) {
|
|
146287
146621
|
next2();
|
|
@@ -146293,6 +146627,16 @@ function createRequestLoggingMiddleware(rootLogger, options = {}) {
|
|
|
146293
146627
|
const logCompletion = (closed) => {
|
|
146294
146628
|
if (logged) return;
|
|
146295
146629
|
logged = true;
|
|
146630
|
+
const throttle = options.throttle;
|
|
146631
|
+
if (throttle && throttle.intervalMs > 0 && throttle.shouldThrottle(req, res, closed, path47)) {
|
|
146632
|
+
const now = throttle.now?.() ?? Date.now();
|
|
146633
|
+
const key2 = throttle.key?.(req, path47) ?? `${req.method.toUpperCase()} ${path47}`;
|
|
146634
|
+
const previousLoggedAt = lastLoggedAt.get(key2);
|
|
146635
|
+
if (previousLoggedAt !== void 0 && now - previousLoggedAt < throttle.intervalMs) {
|
|
146636
|
+
return;
|
|
146637
|
+
}
|
|
146638
|
+
lastLoggedAt.set(key2, now);
|
|
146639
|
+
}
|
|
146296
146640
|
log2.info("request completed", {
|
|
146297
146641
|
method: req.method,
|
|
146298
146642
|
path: path47,
|
|
@@ -146413,8 +146757,21 @@ var sharedMcpControl;
|
|
|
146413
146757
|
var DEFAULT_START_POLL_INTERVAL_MS = 1e4;
|
|
146414
146758
|
var DEFAULT_START_TIMEOUT_MS = 15 * 6e4;
|
|
146415
146759
|
var ALWAYS_ONLINE_STARTABLE_DEVBOX_STATUSES = /* @__PURE__ */ new Set(["hibernated", "stopped"]);
|
|
146760
|
+
var DEVBOX_MCP_NODE_VERSION = "22";
|
|
146416
146761
|
var DEVBOX_MCP_COMMAND = "npx";
|
|
146417
|
-
var DEVBOX_MCP_ARGS = ["-y", "-p",
|
|
146762
|
+
var DEVBOX_MCP_ARGS = ["-y", "-p", `node@${DEVBOX_MCP_NODE_VERSION}`, "-p", "@microsoft/devbox-mcp@latest", "devbox-mcp-server"];
|
|
146763
|
+
var DEVBOX_MCP_DISPLAY_COMMAND = `${DEVBOX_MCP_COMMAND} ${DEVBOX_MCP_ARGS.join(" ")}`;
|
|
146764
|
+
function asDevBoxMcpError(err) {
|
|
146765
|
+
if (err instanceof MeshyError) return err;
|
|
146766
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
146767
|
+
if (!/connection closed/iu.test(cause)) return err;
|
|
146768
|
+
return new MeshyError(
|
|
146769
|
+
"DEVBOX_MCP_UNAVAILABLE",
|
|
146770
|
+
`Unable to reach the DevBox MCP server: it closed the connection. Meshy runs @microsoft/devbox-mcp with Node.js ${DEVBOX_MCP_NODE_VERSION} via npx; check that npx can install packages and Azure Dev Box authentication is available, then try again.`,
|
|
146771
|
+
502,
|
|
146772
|
+
{ cause, command: DEVBOX_MCP_DISPLAY_COMMAND }
|
|
146773
|
+
);
|
|
146774
|
+
}
|
|
146418
146775
|
function getDevBoxControl(deps) {
|
|
146419
146776
|
if (deps.devBoxControl) return deps.devBoxControl;
|
|
146420
146777
|
sharedMcpControl ??= new McpDevBoxControl(deps.logger);
|
|
@@ -146557,7 +146914,7 @@ var McpDevBoxControl = class {
|
|
|
146557
146914
|
return await client.callTool({ name: name2, arguments: args });
|
|
146558
146915
|
} catch (err) {
|
|
146559
146916
|
this.clientPromise = null;
|
|
146560
|
-
throw err;
|
|
146917
|
+
throw asDevBoxMcpError(err);
|
|
146561
146918
|
}
|
|
146562
146919
|
}
|
|
146563
146920
|
async getClient() {
|
|
@@ -146595,13 +146952,13 @@ function cleanDevBoxInfo(devbox) {
|
|
|
146595
146952
|
}
|
|
146596
146953
|
function normalizeMcpDevBoxList(value) {
|
|
146597
146954
|
const normalized = normalizeMcpValue(value);
|
|
146598
|
-
const record2 =
|
|
146955
|
+
const record2 = isRecord10(normalized) ? normalized : {};
|
|
146599
146956
|
const list4 = Array.isArray(normalized) ? normalized : Array.isArray(record2.devboxes) ? record2.devboxes : Array.isArray(record2.value) ? record2.value : [];
|
|
146600
146957
|
return list4.map((item) => normalizeDevBoxResource(item, void 0)).filter((item) => Boolean(item.name));
|
|
146601
146958
|
}
|
|
146602
146959
|
function normalizeDevBoxResource(value, fallback) {
|
|
146603
146960
|
const record2 = normalizeRecord(value);
|
|
146604
|
-
const additional =
|
|
146961
|
+
const additional = isRecord10(record2.additionalProperties) ? record2.additionalProperties : {};
|
|
146605
146962
|
const fromUri = parseDevBoxUri(readString(record2, "uri"));
|
|
146606
146963
|
const status = readString(record2, "status") ?? readString(record2, "powerState") ?? readString(record2, "lastStatus") ?? fallback?.lastStatus;
|
|
146607
146964
|
const name2 = readString(record2, "name") ?? fromUri?.name ?? fallback?.name ?? "";
|
|
@@ -146655,7 +147012,7 @@ function parseDevCenterEndpoint(hostname6) {
|
|
|
146655
147012
|
}
|
|
146656
147013
|
function normalizeRecord(value) {
|
|
146657
147014
|
const normalized = normalizeMcpValue(value);
|
|
146658
|
-
return
|
|
147015
|
+
return isRecord10(normalized) ? normalized : {};
|
|
146659
147016
|
}
|
|
146660
147017
|
function normalizeMcpValue(value) {
|
|
146661
147018
|
if (Array.isArray(value)) return value;
|
|
@@ -146690,7 +147047,7 @@ function tryParseJson(text10) {
|
|
|
146690
147047
|
return null;
|
|
146691
147048
|
}
|
|
146692
147049
|
}
|
|
146693
|
-
function
|
|
147050
|
+
function isRecord10(value) {
|
|
146694
147051
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
146695
147052
|
}
|
|
146696
147053
|
function readString(record2, key2) {
|
|
@@ -147982,6 +148339,7 @@ function buildNodeSettingsSnapshot(options) {
|
|
|
147982
148339
|
version: runtimeMetadata?.packageVersion ?? "0.1.0",
|
|
147983
148340
|
packageName: runtimeMetadata?.packageName ?? "meshy",
|
|
147984
148341
|
uptime,
|
|
148342
|
+
defaultTaskAgent: options.defaultTaskAgent,
|
|
147985
148343
|
auth: options.auth,
|
|
147986
148344
|
os: getOsSnapshot(),
|
|
147987
148345
|
runtime: {
|
|
@@ -148014,6 +148372,7 @@ function buildSystemInfo(deps) {
|
|
|
148014
148372
|
};
|
|
148015
148373
|
const settingsSnapshot = buildNodeSettingsSnapshot({
|
|
148016
148374
|
auth,
|
|
148375
|
+
defaultTaskAgent: deps.storagePath ? resolveNodeDefaultTaskAgent(deps.storagePath) : "codex",
|
|
148017
148376
|
inspectRuntimeTools: deps.inspectRuntimeTools,
|
|
148018
148377
|
localDashboardOrigin: deps.localDashboardOrigin,
|
|
148019
148378
|
runtimeMetadata: deps.runtimeMetadata,
|
|
@@ -148027,6 +148386,7 @@ function buildSystemInfo(deps) {
|
|
|
148027
148386
|
version: settingsSnapshot.version,
|
|
148028
148387
|
packageName: settingsSnapshot.packageName,
|
|
148029
148388
|
uptime: settingsSnapshot.uptime,
|
|
148389
|
+
defaultTaskAgent: settingsSnapshot.defaultTaskAgent,
|
|
148030
148390
|
transportType: deps.getTransportType?.() ?? "direct",
|
|
148031
148391
|
dashboardOrigin: deps.dashboardOrigin ?? self2.dashboardOrigin,
|
|
148032
148392
|
localDashboardOrigin: deps.localDashboardOrigin,
|
|
@@ -148117,7 +148477,7 @@ function upgradeRuntimeAgentForDeps(deps, agent) {
|
|
|
148117
148477
|
// ../../packages/api/src/node/runtime-restart-request.ts
|
|
148118
148478
|
init_cjs_shims();
|
|
148119
148479
|
function parseRuntimeRestartRequest(value) {
|
|
148120
|
-
const body3 =
|
|
148480
|
+
const body3 = isRecord11(value) ? value : {};
|
|
148121
148481
|
const startArgs = parseRuntimeRestartStartArgs(body3.startArgs);
|
|
148122
148482
|
return {
|
|
148123
148483
|
reason: body3.reason === "update" ? "update" : "restart",
|
|
@@ -148126,7 +148486,7 @@ function parseRuntimeRestartRequest(value) {
|
|
|
148126
148486
|
}
|
|
148127
148487
|
function parseRuntimeRestartStartArgs(value) {
|
|
148128
148488
|
if (value === void 0) return void 0;
|
|
148129
|
-
if (!
|
|
148489
|
+
if (!isRecord11(value)) {
|
|
148130
148490
|
throw new MeshyError("VALIDATION_ERROR", "Runtime restart startArgs must be an object", 400);
|
|
148131
148491
|
}
|
|
148132
148492
|
const startArgs = {};
|
|
@@ -148175,7 +148535,7 @@ function parseOptionalString(value, key2) {
|
|
|
148175
148535
|
const trimmed = value.trim();
|
|
148176
148536
|
return trimmed || void 0;
|
|
148177
148537
|
}
|
|
148178
|
-
function
|
|
148538
|
+
function isRecord11(value) {
|
|
148179
148539
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
148180
148540
|
}
|
|
148181
148541
|
|
|
@@ -149196,7 +149556,7 @@ function toLegacyWorkerControl2(message) {
|
|
|
149196
149556
|
}
|
|
149197
149557
|
|
|
149198
149558
|
// ../../packages/api/src/tasks/task-route-utils.ts
|
|
149199
|
-
function
|
|
149559
|
+
function isRecord12(value) {
|
|
149200
149560
|
return typeof value === "object" && value !== null;
|
|
149201
149561
|
}
|
|
149202
149562
|
function restoreTaskState(taskEngine, task) {
|
|
@@ -149263,7 +149623,7 @@ function normalizeStructuredValue(value) {
|
|
|
149263
149623
|
if (Array.isArray(value)) {
|
|
149264
149624
|
return value.map((entry) => normalizeStructuredValue(entry));
|
|
149265
149625
|
}
|
|
149266
|
-
if (!
|
|
149626
|
+
if (!isRecord12(value)) {
|
|
149267
149627
|
return value;
|
|
149268
149628
|
}
|
|
149269
149629
|
return Object.fromEntries(
|
|
@@ -149272,20 +149632,20 @@ function normalizeStructuredValue(value) {
|
|
|
149272
149632
|
}
|
|
149273
149633
|
function getTranscriptEventSignature(event) {
|
|
149274
149634
|
if (event.type === "user") {
|
|
149275
|
-
const signature = getTaskUserMessageSignature(
|
|
149635
|
+
const signature = getTaskUserMessageSignature(isRecord12(event.message) ? event.message.content : event.message) ?? getTaskUserMessageSignature(event.content);
|
|
149276
149636
|
return signature ? `user:${signature}` : null;
|
|
149277
149637
|
}
|
|
149278
149638
|
if (event.type === "assistant") {
|
|
149279
149639
|
if (typeof event.message === "string") {
|
|
149280
149640
|
return `assistant:${JSON.stringify(event.message)}`;
|
|
149281
149641
|
}
|
|
149282
|
-
if (
|
|
149642
|
+
if (isRecord12(event.message) && "content" in event.message) {
|
|
149283
149643
|
return `assistant:${JSON.stringify(normalizeStructuredValue(event.message.content))}`;
|
|
149284
149644
|
}
|
|
149285
149645
|
if (Array.isArray(event.content)) {
|
|
149286
149646
|
return `assistant:${JSON.stringify(normalizeStructuredValue(event.content))}`;
|
|
149287
149647
|
}
|
|
149288
|
-
if (
|
|
149648
|
+
if (isRecord12(event.message)) {
|
|
149289
149649
|
return `assistant:${JSON.stringify(normalizeStructuredValue(event.message))}`;
|
|
149290
149650
|
}
|
|
149291
149651
|
}
|
|
@@ -177128,22 +177488,32 @@ async function handleTaskMessage(deps, message) {
|
|
|
177128
177488
|
if (!task) {
|
|
177129
177489
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${payload.taskId} not found`, 404);
|
|
177130
177490
|
}
|
|
177131
|
-
|
|
177132
|
-
|
|
177491
|
+
const targetAgent = typeof payload.targetAgent === "string" ? payload.targetAgent : void 0;
|
|
177492
|
+
const agent = resolveActiveAgent(task, targetAgent);
|
|
177493
|
+
if (!supportsFollowUpAgent(agent)) {
|
|
177494
|
+
throw new MeshyError("VALIDATION_ERROR", `Agent ${agent} does not support chat messages`, 400);
|
|
177133
177495
|
}
|
|
177134
|
-
const engine = deps.engineRegistry.get(
|
|
177496
|
+
const engine = deps.engineRegistry.get(agent);
|
|
177135
177497
|
if (!engine) {
|
|
177136
|
-
throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${
|
|
177498
|
+
throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${agent}`, 400);
|
|
177137
177499
|
}
|
|
177138
|
-
deps.taskEngine.updateTask(payload.taskId, { status: "running" });
|
|
177139
177500
|
if (!deps.nodeRegistry.isLeader()) {
|
|
177140
177501
|
const reporter = new RestLeaderTaskReporter(deps.nodeRegistry, log2);
|
|
177141
177502
|
reporter.reportRunning(payload.taskId, { branch: task.branch });
|
|
177142
|
-
registerLeaderForwarding(deps.eventBus, deps.nodeRegistry, log2, payload.taskId,
|
|
177503
|
+
registerLeaderForwarding(deps.eventBus, deps.nodeRegistry, log2, payload.taskId, agent, reporter);
|
|
177143
177504
|
}
|
|
177144
177505
|
try {
|
|
177145
|
-
|
|
177146
|
-
|
|
177506
|
+
startAgentTaskTurn({
|
|
177507
|
+
task,
|
|
177508
|
+
content: payload.content,
|
|
177509
|
+
targetAgent,
|
|
177510
|
+
assignedTo: task.assignedTo,
|
|
177511
|
+
taskEngine: deps.taskEngine,
|
|
177512
|
+
engineRegistry: deps.engineRegistry,
|
|
177513
|
+
eventBus: deps.eventBus,
|
|
177514
|
+
logger: log2
|
|
177515
|
+
});
|
|
177516
|
+
log2.info("started follow-up execution", { taskId: payload.taskId, agent });
|
|
177147
177517
|
} catch (error2) {
|
|
177148
177518
|
const messageText = error2 instanceof Error ? error2.message : String(error2);
|
|
177149
177519
|
log2.error("engine.sendMessage threw synchronously", { taskId: payload.taskId, error: messageText });
|
|
@@ -177394,6 +177764,7 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
177394
177764
|
const log2 = rootLogger.child("tasks/logs");
|
|
177395
177765
|
const query = TaskLogsQuery.parse(req.query);
|
|
177396
177766
|
const after = query.after ?? 0;
|
|
177767
|
+
const minTotal = query.minTotal ?? 0;
|
|
177397
177768
|
const proxyRequest = getTaskLogsProxyRequestMetadata(req);
|
|
177398
177769
|
let task = taskEngine.getTask(taskId);
|
|
177399
177770
|
if (!task && proxyRequest.task?.id === taskId) {
|
|
@@ -177439,7 +177810,8 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
177439
177810
|
if (isLeader) {
|
|
177440
177811
|
const local2 = readLocalTaskLogsWithNativeHistory(engineRegistry, task, taskId, after, task?.agent ?? "claudecode");
|
|
177441
177812
|
leaderLocal = local2;
|
|
177442
|
-
|
|
177813
|
+
const leaderLocalSatisfiesCheckpoint = minTotal === 0 || local2.total >= minTotal;
|
|
177814
|
+
if ((local2.total > 0 || !needsProxy) && leaderLocalSatisfiesCheckpoint && !shouldAskWorkerForNativeRepair) {
|
|
177443
177815
|
log2.debug("serving leader-local task logs", {
|
|
177444
177816
|
taskId,
|
|
177445
177817
|
assignedTo: task?.assignedTo,
|
|
@@ -177450,7 +177822,16 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
177450
177822
|
res.json(local2);
|
|
177451
177823
|
return;
|
|
177452
177824
|
}
|
|
177453
|
-
if (local2.total > 0 &&
|
|
177825
|
+
if (local2.total > 0 && !leaderLocalSatisfiesCheckpoint) {
|
|
177826
|
+
log2.debug("leader-local task logs behind requested checkpoint, falling back to worker proxy", {
|
|
177827
|
+
taskId,
|
|
177828
|
+
assignedTo: task?.assignedTo,
|
|
177829
|
+
selfId,
|
|
177830
|
+
total: local2.total,
|
|
177831
|
+
minTotal,
|
|
177832
|
+
after
|
|
177833
|
+
});
|
|
177834
|
+
} else if (local2.total > 0 && shouldAskWorkerForNativeRepair) {
|
|
177454
177835
|
log2.debug("leader-local native session logs may be partial, checking worker repair path", {
|
|
177455
177836
|
taskId,
|
|
177456
177837
|
assignedTo: task?.assignedTo,
|
|
@@ -177493,7 +177874,9 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
177493
177874
|
return;
|
|
177494
177875
|
}
|
|
177495
177876
|
}
|
|
177496
|
-
const
|
|
177877
|
+
const proxyParams = new URLSearchParams({ after: String(after) });
|
|
177878
|
+
if (minTotal > 0) proxyParams.set("minTotal", String(minTotal));
|
|
177879
|
+
const proxyPath = `/api/tasks/${taskId}/logs?${proxyParams.toString()}`;
|
|
177497
177880
|
try {
|
|
177498
177881
|
const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
|
|
177499
177882
|
node2,
|
|
@@ -177548,17 +177931,24 @@ init_cjs_shims();
|
|
|
177548
177931
|
|
|
177549
177932
|
// ../../packages/api/src/tasks/task-follow-up.ts
|
|
177550
177933
|
init_cjs_shims();
|
|
177551
|
-
function startLocalTaskFollowUp(deps, task, content3, assignedTo, metadata) {
|
|
177552
|
-
const
|
|
177934
|
+
function startLocalTaskFollowUp(deps, task, content3, assignedTo, targetAgent, metadata) {
|
|
177935
|
+
const agent = resolveActiveAgent(task, targetAgent);
|
|
177936
|
+
const engine = deps.engineRegistry.get(agent);
|
|
177553
177937
|
if (!engine) {
|
|
177554
|
-
throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${
|
|
177938
|
+
throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${agent}`, 400);
|
|
177555
177939
|
}
|
|
177556
|
-
deps.taskEngine.updateTask(task.id, {
|
|
177557
|
-
status: "running",
|
|
177558
|
-
assignedTo
|
|
177559
|
-
});
|
|
177560
177940
|
try {
|
|
177561
|
-
|
|
177941
|
+
startAgentTaskTurn({
|
|
177942
|
+
task,
|
|
177943
|
+
content: content3,
|
|
177944
|
+
targetAgent,
|
|
177945
|
+
assignedTo,
|
|
177946
|
+
taskEngine: deps.taskEngine,
|
|
177947
|
+
engineRegistry: deps.engineRegistry,
|
|
177948
|
+
eventBus: deps.eventBus,
|
|
177949
|
+
logger: deps.logger,
|
|
177950
|
+
metadata
|
|
177951
|
+
});
|
|
177562
177952
|
} catch (err) {
|
|
177563
177953
|
restoreTaskState(deps.taskEngine, task);
|
|
177564
177954
|
deps.logger.warn("failed to start local follow-up execution", {
|
|
@@ -177581,9 +177971,10 @@ function restoreQueuedMessage(taskEngine, taskId, message) {
|
|
|
177581
177971
|
queuedMessages: [message, ...current.queuedMessages ?? []]
|
|
177582
177972
|
});
|
|
177583
177973
|
}
|
|
177584
|
-
async function sendTaskFollowUpMessage(deps, task, content3, metadata) {
|
|
177585
|
-
|
|
177586
|
-
|
|
177974
|
+
async function sendTaskFollowUpMessage(deps, task, content3, targetAgent, metadata) {
|
|
177975
|
+
const agent = resolveActiveAgent(task, targetAgent);
|
|
177976
|
+
if (!supportsFollowUpAgent(agent)) {
|
|
177977
|
+
throw new MeshyError("VALIDATION_ERROR", `Agent ${agent} does not support chat messages`, 400);
|
|
177587
177978
|
}
|
|
177588
177979
|
if (task.assignedTo && task.assignedTo !== deps.nodeRegistry.getSelf()?.id) {
|
|
177589
177980
|
const node2 = deps.nodeRegistry.getNode(task.assignedTo);
|
|
@@ -177602,7 +177993,7 @@ async function sendTaskFollowUpMessage(deps, task, content3, metadata) {
|
|
|
177602
177993
|
409
|
|
177603
177994
|
);
|
|
177604
177995
|
}
|
|
177605
|
-
deps.taskEngine.updateTask(task.id, { status: "running" });
|
|
177996
|
+
deps.taskEngine.updateTask(task.id, targetAgent ? { status: "running", payload: { ...task.payload, activeAgent: agent } } : { status: "running" });
|
|
177606
177997
|
log2.info("proxying follow-up message to worker", {
|
|
177607
177998
|
taskId: task.id,
|
|
177608
177999
|
assignedTo: task.assignedTo,
|
|
@@ -177612,7 +178003,8 @@ async function sendTaskFollowUpMessage(deps, task, content3, metadata) {
|
|
|
177612
178003
|
const client = new NodeMessageClient({ heartbeat: deps.heartbeat, logger: deps.logger });
|
|
177613
178004
|
const delivery = await client.send(node2, createNodeMessage("task.message", {
|
|
177614
178005
|
taskId: task.id,
|
|
177615
|
-
content: content3
|
|
178006
|
+
content: content3,
|
|
178007
|
+
...targetAgent ? { targetAgent } : {}
|
|
177616
178008
|
}));
|
|
177617
178009
|
return delivery.queued ? { queued: true } : {};
|
|
177618
178010
|
} catch (err) {
|
|
@@ -177630,31 +178022,34 @@ async function sendTaskFollowUpMessage(deps, task, content3, metadata) {
|
|
|
177630
178022
|
startLocalTaskFollowUp({
|
|
177631
178023
|
taskEngine: deps.taskEngine,
|
|
177632
178024
|
engineRegistry: deps.engineRegistry,
|
|
178025
|
+
eventBus: deps.eventBus,
|
|
177633
178026
|
logger: deps.logger.child("tasks/message")
|
|
177634
|
-
}, task, content3, task.assignedTo, metadata);
|
|
178027
|
+
}, task, content3, task.assignedTo, targetAgent, metadata);
|
|
177635
178028
|
return {};
|
|
177636
178029
|
}
|
|
177637
|
-
function queueRunningTaskMessage(deps, task, content3) {
|
|
177638
|
-
|
|
177639
|
-
|
|
178030
|
+
function queueRunningTaskMessage(deps, task, content3, targetAgent) {
|
|
178031
|
+
const agent = resolveActiveAgent(task, targetAgent);
|
|
178032
|
+
if (!supportsFollowUpAgent(agent)) {
|
|
178033
|
+
throw new MeshyError("VALIDATION_ERROR", `Agent ${agent} does not support chat messages`, 400);
|
|
177640
178034
|
}
|
|
177641
|
-
const queued = deps.taskEngine.enqueueTaskMessage(task.id, content3);
|
|
178035
|
+
const queued = targetAgent ? deps.taskEngine.enqueueTaskMessage(task.id, content3, targetAgent) : deps.taskEngine.enqueueTaskMessage(task.id, content3);
|
|
177642
178036
|
deps.logger.child("tasks/message").info("queued follow-up message for running task", {
|
|
177643
178037
|
taskId: task.id,
|
|
178038
|
+
targetAgent,
|
|
177644
178039
|
queuedCount: queued.queuedMessages?.length ?? 0
|
|
177645
178040
|
});
|
|
177646
178041
|
return queued;
|
|
177647
178042
|
}
|
|
177648
178043
|
var MESSAGEABLE_STATUSES = /* @__PURE__ */ new Set(["running", "completed", "cancelled", "failed"]);
|
|
177649
|
-
async function applyTaskMessage(deps, task, content3) {
|
|
178044
|
+
async function applyTaskMessage(deps, task, content3, targetAgent) {
|
|
177650
178045
|
if (!MESSAGEABLE_STATUSES.has(task.status)) {
|
|
177651
178046
|
throw new MeshyError("VALIDATION_ERROR", `Cannot send message to task in ${task.status} status`, 400);
|
|
177652
178047
|
}
|
|
177653
178048
|
if (task.status === "running") {
|
|
177654
|
-
const queued = queueRunningTaskMessage(deps, task, content3);
|
|
178049
|
+
const queued = queueRunningTaskMessage(deps, task, content3, targetAgent);
|
|
177655
178050
|
return { ok: true, queued: true, queuedMessages: queued.queuedMessages ?? [] };
|
|
177656
178051
|
}
|
|
177657
|
-
const result = await sendTaskFollowUpMessage(deps, task, content3);
|
|
178052
|
+
const result = await sendTaskFollowUpMessage(deps, task, content3, targetAgent);
|
|
177658
178053
|
return result.queued ? { ok: true, queued: true } : { ok: true };
|
|
177659
178054
|
}
|
|
177660
178055
|
function cancelQueuedTaskMessage(deps, taskId, messageId) {
|
|
@@ -177687,7 +178082,7 @@ async function drainNextQueuedTaskMessage(deps, taskId) {
|
|
|
177687
178082
|
if (!dequeued) return false;
|
|
177688
178083
|
drainingTaskIds.add(taskId);
|
|
177689
178084
|
try {
|
|
177690
|
-
await sendTaskFollowUpMessage(deps, dequeued.task, dequeued.message.content, {
|
|
178085
|
+
await sendTaskFollowUpMessage(deps, dequeued.task, dequeued.message.content, dequeued.message.targetAgent, {
|
|
177691
178086
|
queuedMessageId: dequeued.message.id
|
|
177692
178087
|
});
|
|
177693
178088
|
deps.logger.child("tasks/message").info("started queued follow-up message", {
|
|
@@ -178671,7 +179066,7 @@ function createTaskRoutes() {
|
|
|
178671
179066
|
res.json({ ok: true, queuedMessages: task.queuedMessages ?? [] });
|
|
178672
179067
|
}));
|
|
178673
179068
|
router.post("/:id/message", asyncHandler8(async (req, res) => {
|
|
178674
|
-
const { taskEngine, engineRegistry, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
179069
|
+
const { taskEngine, engineRegistry, nodeRegistry, heartbeat, eventBus, logger: rootLogger } = req.app.locals.deps;
|
|
178675
179070
|
const body3 = SendMessageBody.parse(req.body);
|
|
178676
179071
|
const taskId = req.params.id;
|
|
178677
179072
|
const task = taskEngine.getTask(taskId);
|
|
@@ -178679,9 +179074,10 @@ function createTaskRoutes() {
|
|
|
178679
179074
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
178680
179075
|
}
|
|
178681
179076
|
res.json(await applyTaskMessage(
|
|
178682
|
-
{ taskEngine, engineRegistry, nodeRegistry, heartbeat, logger: rootLogger },
|
|
179077
|
+
{ taskEngine, engineRegistry, nodeRegistry, heartbeat, eventBus, logger: rootLogger },
|
|
178683
179078
|
task,
|
|
178684
|
-
body3.content
|
|
179079
|
+
body3.content,
|
|
179080
|
+
body3.targetAgent
|
|
178685
179081
|
));
|
|
178686
179082
|
}));
|
|
178687
179083
|
router.use(createTaskOutputRoutes());
|
|
@@ -178855,6 +179251,10 @@ var WorkerMessageBody = external_exports.object({
|
|
|
178855
179251
|
var WorkerTaskBody = external_exports.object({
|
|
178856
179252
|
taskId: external_exports.string().min(1)
|
|
178857
179253
|
});
|
|
179254
|
+
var WorkerLogsReadyBody = external_exports.object({
|
|
179255
|
+
taskId: external_exports.string().min(1),
|
|
179256
|
+
total: external_exports.number().int().min(0)
|
|
179257
|
+
});
|
|
178858
179258
|
function asyncHandler10(fn) {
|
|
178859
179259
|
return (req, res, next2) => fn(req, res, next2).catch(next2);
|
|
178860
179260
|
}
|
|
@@ -178909,15 +179309,15 @@ function createWorkerRoutes() {
|
|
|
178909
179309
|
if (!task) {
|
|
178910
179310
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${body3.taskId} not found`, 404);
|
|
178911
179311
|
}
|
|
178912
|
-
|
|
178913
|
-
|
|
179312
|
+
const agent = resolveActiveAgent(task, body3.targetAgent);
|
|
179313
|
+
if (!supportsFollowUpAgent(agent)) {
|
|
179314
|
+
throw new MeshyError("VALIDATION_ERROR", `Agent ${agent} does not support chat messages`, 400);
|
|
178914
179315
|
}
|
|
178915
|
-
const engine = engineRegistry.get(
|
|
179316
|
+
const engine = engineRegistry.get(agent);
|
|
178916
179317
|
if (!engine) {
|
|
178917
|
-
res.status(400).json({ error: `Engine not registered for agent: ${
|
|
179318
|
+
res.status(400).json({ error: `Engine not registered for agent: ${agent}` });
|
|
178918
179319
|
return;
|
|
178919
179320
|
}
|
|
178920
|
-
taskEngine.updateTask(body3.taskId, { status: "running" });
|
|
178921
179321
|
if (!nodeRegistry.isLeader()) {
|
|
178922
179322
|
new RestLeaderTaskReporter(nodeRegistry, log2).reportRunning(body3.taskId, { branch: task.branch });
|
|
178923
179323
|
}
|
|
@@ -178928,13 +179328,22 @@ function createWorkerRoutes() {
|
|
|
178928
179328
|
nodeRegistry,
|
|
178929
179329
|
log2,
|
|
178930
179330
|
body3.taskId,
|
|
178931
|
-
|
|
179331
|
+
agent,
|
|
178932
179332
|
new RestLeaderTaskReporter(nodeRegistry, log2)
|
|
178933
179333
|
);
|
|
178934
179334
|
}
|
|
178935
179335
|
try {
|
|
178936
|
-
|
|
178937
|
-
|
|
179336
|
+
startAgentTaskTurn({
|
|
179337
|
+
task,
|
|
179338
|
+
content: body3.content,
|
|
179339
|
+
targetAgent: body3.targetAgent,
|
|
179340
|
+
assignedTo: task.assignedTo,
|
|
179341
|
+
taskEngine,
|
|
179342
|
+
engineRegistry,
|
|
179343
|
+
eventBus,
|
|
179344
|
+
logger: log2
|
|
179345
|
+
});
|
|
179346
|
+
log2.info("started follow-up execution", { taskId: body3.taskId, agent });
|
|
178938
179347
|
} catch (err) {
|
|
178939
179348
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
178940
179349
|
log2.error("engine.sendMessage threw synchronously", { taskId: body3.taskId, error: errorMessage });
|
|
@@ -178986,6 +179395,12 @@ function createWorkerRoutes() {
|
|
|
178986
179395
|
}
|
|
178987
179396
|
res.json({ ok: true });
|
|
178988
179397
|
}));
|
|
179398
|
+
router.post("/logs-ready", asyncHandler10(async (req, res) => {
|
|
179399
|
+
const { eventBus } = req.app.locals.deps;
|
|
179400
|
+
const body3 = WorkerLogsReadyBody.parse(req.body);
|
|
179401
|
+
eventBus.emit("task.logs.ready", { taskId: body3.taskId, total: body3.total });
|
|
179402
|
+
res.json({ ok: true });
|
|
179403
|
+
}));
|
|
178989
179404
|
router.post("/heartbeat", asyncHandler10(async (req, res) => {
|
|
178990
179405
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
178991
179406
|
const log2 = rootLogger.child("worker/heartbeat");
|
|
@@ -179156,6 +179571,10 @@ function getQuickChatStore(deps) {
|
|
|
179156
179571
|
if (deps.storagePath) return createQuickChatStore(deps.storagePath);
|
|
179157
179572
|
throw new MeshyError("VALIDATION_ERROR", "Quick chats are not available for this node", 501);
|
|
179158
179573
|
}
|
|
179574
|
+
function getStoragePath2(deps) {
|
|
179575
|
+
if (deps.storagePath) return deps.storagePath;
|
|
179576
|
+
throw new MeshyError("VALIDATION_ERROR", "Node metadata is not available for this node", 501);
|
|
179577
|
+
}
|
|
179159
179578
|
function validateQuickChatAliases(quickChats) {
|
|
179160
179579
|
const seen = /* @__PURE__ */ new Set();
|
|
179161
179580
|
for (const quickChat of quickChats) {
|
|
@@ -179248,6 +179667,21 @@ function createSystemRoutes() {
|
|
|
179248
179667
|
const metrics2 = taskEngine.getMetrics();
|
|
179249
179668
|
res.json(metrics2);
|
|
179250
179669
|
}));
|
|
179670
|
+
router.get("/default-task-agent", asyncHandler11(async (req, res) => {
|
|
179671
|
+
const storagePath = getStoragePath2(req.app.locals.deps);
|
|
179672
|
+
res.json({ defaultTaskAgent: resolveNodeDefaultTaskAgent(storagePath) });
|
|
179673
|
+
}));
|
|
179674
|
+
router.put("/default-task-agent", asyncHandler11(async (req, res) => {
|
|
179675
|
+
const body3 = UpdateDefaultTaskAgentBody.parse(req.body);
|
|
179676
|
+
const deps = req.app.locals.deps;
|
|
179677
|
+
const storagePath = getStoragePath2(deps);
|
|
179678
|
+
persistNodeDefaultTaskAgent(storagePath, body3.defaultTaskAgent);
|
|
179679
|
+
const settingsSnapshot = deps.refreshSettingsSnapshot?.();
|
|
179680
|
+
if (settingsSnapshot) {
|
|
179681
|
+
deps.nodeRegistry.updateSettingsSnapshot(deps.nodeRegistry.getSelf().id, settingsSnapshot);
|
|
179682
|
+
}
|
|
179683
|
+
res.json({ defaultTaskAgent: resolveNodeDefaultTaskAgent(storagePath) });
|
|
179684
|
+
}));
|
|
179251
179685
|
router.get("/quick-chats", asyncHandler11(async (req, res) => {
|
|
179252
179686
|
const store = getQuickChatStore(req.app.locals.deps);
|
|
179253
179687
|
res.json({ quickChats: store.list() });
|
|
@@ -179284,6 +179718,7 @@ var ALL_EVENT_NAMES = [
|
|
|
179284
179718
|
"task.updated",
|
|
179285
179719
|
"task.deleted",
|
|
179286
179720
|
"task.output",
|
|
179721
|
+
"task.logs.ready",
|
|
179287
179722
|
"election.started",
|
|
179288
179723
|
"election.complete",
|
|
179289
179724
|
"cluster.state",
|
|
@@ -179590,12 +180025,22 @@ var REQUEST_TELEMETRY_SUPPRESSED_ROUTES = /* @__PURE__ */ new Set([
|
|
|
179590
180025
|
"POST /api/cluster-control/heartbeat",
|
|
179591
180026
|
"POST /api/cluster-control/keepalive"
|
|
179592
180027
|
]);
|
|
180028
|
+
var REQUEST_LOGGING_THROTTLED_ROUTES = /* @__PURE__ */ new Set([
|
|
180029
|
+
"POST /api/worker/keepalive",
|
|
180030
|
+
"POST /api/cluster-control/keepalive"
|
|
180031
|
+
]);
|
|
180032
|
+
var REQUEST_LOGGING_THROTTLE_MS = 6e4;
|
|
179593
180033
|
function normalizeRequestTelemetryPath(pathname) {
|
|
179594
180034
|
return pathname.length > 1 ? pathname.replace(/\/+$/, "") : pathname;
|
|
179595
180035
|
}
|
|
180036
|
+
function requestRouteKey(method, pathname) {
|
|
180037
|
+
return `${method.toUpperCase()} ${normalizeRequestTelemetryPath(pathname)}`;
|
|
180038
|
+
}
|
|
179596
180039
|
function isSuppressedRequestTelemetryRoute(req) {
|
|
179597
|
-
|
|
179598
|
-
|
|
180040
|
+
return REQUEST_TELEMETRY_SUPPRESSED_ROUTES.has(requestRouteKey(req.method, req.path));
|
|
180041
|
+
}
|
|
180042
|
+
function isThrottledRequestLoggingRoute(method, pathname) {
|
|
180043
|
+
return REQUEST_LOGGING_THROTTLED_ROUTES.has(requestRouteKey(method, pathname));
|
|
179599
180044
|
}
|
|
179600
180045
|
function usesLargeJsonBodyLimit(pathname) {
|
|
179601
180046
|
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/") || pathname.startsWith("/api/mobile/");
|
|
@@ -179767,7 +180212,11 @@ function createServer2(deps) {
|
|
|
179767
180212
|
const canServeDashboard = (req) => !deps.config.validateBearerToken || isTrustedDashboardRequest(req, authConfig);
|
|
179768
180213
|
const canServePreview = (req) => canServeDashboard(req) || hasAuthorizationHeader(req);
|
|
179769
180214
|
app.use(createRequestLoggingMiddleware(deps.logger, {
|
|
179770
|
-
shouldLog: (req) => isApiRequest(req) || isPreviewRequest(req)
|
|
180215
|
+
shouldLog: (req) => isApiRequest(req) || isPreviewRequest(req),
|
|
180216
|
+
throttle: {
|
|
180217
|
+
intervalMs: REQUEST_LOGGING_THROTTLE_MS,
|
|
180218
|
+
shouldThrottle: (req, res, closed, path47) => !closed && res.statusCode < 400 && isThrottledRequestLoggingRoute(req.method, path47)
|
|
180219
|
+
}
|
|
179771
180220
|
}));
|
|
179772
180221
|
app.use(createRequestTelemetryMiddleware(deps.telemetry ?? createNoopTelemetry(), {
|
|
179773
180222
|
shouldTrack: (req) => !isSuppressedRequestTelemetryRoute(req) && (isApiRequest(req) || isPreviewRequest(req))
|
|
@@ -181756,6 +182205,7 @@ function createSettingsSnapshotProvider(options) {
|
|
|
181756
182205
|
function buildSnapshot() {
|
|
181757
182206
|
cachedSnapshot = buildNodeSettingsSnapshot({
|
|
181758
182207
|
auth: options.authMetadata,
|
|
182208
|
+
defaultTaskAgent: resolveNodeDefaultTaskAgent(options.storagePath),
|
|
181759
182209
|
localDashboardOrigin: options.localDashboardOrigin,
|
|
181760
182210
|
runtimeMetadata: options.runtimeMetadata,
|
|
181761
182211
|
runtimeUpdate: createRuntimeUpdateSnapshot({
|