@gethmy/agent 1.10.1 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +79 -19
- package/dist/index.js +75 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2318,7 +2318,8 @@ function buildTokenPayload(stats) {
|
|
|
2318
2318
|
outputTokens: stats.cost.totalOutputTokens,
|
|
2319
2319
|
cacheCreationInputTokens: stats.cost.totalCacheCreationInputTokens,
|
|
2320
2320
|
cacheReadInputTokens: stats.cost.totalCacheReadInputTokens,
|
|
2321
|
-
modelName: stats.cost.modelName
|
|
2321
|
+
modelName: stats.cost.modelName,
|
|
2322
|
+
numTurns: stats.cost.numTurns
|
|
2322
2323
|
};
|
|
2323
2324
|
}
|
|
2324
2325
|
async function runCompletion(client, card, branchName, worktreePath, config, workerId, sessionStats, workspaceId, agentSessionId, stateStore, onMovedToCompletion) {
|
|
@@ -2904,7 +2905,8 @@ class ProgressTracker {
|
|
|
2904
2905
|
outputTokens: this.lastCost?.totalOutputTokens ?? 0,
|
|
2905
2906
|
cacheCreationInputTokens: this.lastCost?.totalCacheCreationInputTokens ?? 0,
|
|
2906
2907
|
cacheReadInputTokens: this.lastCost?.totalCacheReadInputTokens ?? 0,
|
|
2907
|
-
modelName: this.lastCost?.modelName
|
|
2908
|
+
modelName: this.lastCost?.modelName,
|
|
2909
|
+
numTurns: this.lastCost?.numTurns ?? 0
|
|
2908
2910
|
}).catch((err) => {
|
|
2909
2911
|
log.warn(TAG14, `Failed to send progress update: ${err}`);
|
|
2910
2912
|
});
|
|
@@ -3675,13 +3677,19 @@ class StateStore {
|
|
|
3675
3677
|
heartbeat(runId) {
|
|
3676
3678
|
return this.updateRun(runId, { lastHeartbeatAt: Date.now() });
|
|
3677
3679
|
}
|
|
3678
|
-
endRun(runId, status,
|
|
3680
|
+
endRun(runId, status, opts = {}) {
|
|
3679
3681
|
const patch = {
|
|
3680
3682
|
status,
|
|
3681
3683
|
endedAt: Date.now()
|
|
3682
3684
|
};
|
|
3683
|
-
if (errorMessage !== undefined)
|
|
3684
|
-
patch.errorMessage = errorMessage;
|
|
3685
|
+
if (opts.errorMessage !== undefined)
|
|
3686
|
+
patch.errorMessage = opts.errorMessage;
|
|
3687
|
+
if (opts.costCents !== undefined && opts.costCents > 0) {
|
|
3688
|
+
patch.costCents = opts.costCents;
|
|
3689
|
+
}
|
|
3690
|
+
if (opts.numTurns !== undefined && opts.numTurns > 0) {
|
|
3691
|
+
patch.numTurns = opts.numTurns;
|
|
3692
|
+
}
|
|
3685
3693
|
return this.updateRun(runId, patch);
|
|
3686
3694
|
}
|
|
3687
3695
|
getRun(runId) {
|
|
@@ -4113,6 +4121,19 @@ class ReviewWorker {
|
|
|
4113
4121
|
get isActive() {
|
|
4114
4122
|
return this.state === "preparing" || this.state === "running" || this.state === "verifying" || this.state === "completing";
|
|
4115
4123
|
}
|
|
4124
|
+
get costCents() {
|
|
4125
|
+
const cost = (this.progressTracker?.stats ?? this.lastSessionStats)?.cost;
|
|
4126
|
+
return cost ? Math.round(cost.totalCostUsd * 100) : 0;
|
|
4127
|
+
}
|
|
4128
|
+
endLedger() {
|
|
4129
|
+
const cost = (this.lastSessionStats ?? this.progressTracker?.stats)?.cost;
|
|
4130
|
+
if (!cost)
|
|
4131
|
+
return { costCents: 0, numTurns: 0 };
|
|
4132
|
+
return {
|
|
4133
|
+
costCents: Math.round(cost.totalCostUsd * 100),
|
|
4134
|
+
numTurns: cost.numTurns
|
|
4135
|
+
};
|
|
4136
|
+
}
|
|
4116
4137
|
async run(card, column, labels, subtasks) {
|
|
4117
4138
|
this.aborted = false;
|
|
4118
4139
|
this.timedOut = false;
|
|
@@ -4138,7 +4159,8 @@ class ReviewWorker {
|
|
|
4138
4159
|
lastHeartbeatAt: this.startedAt,
|
|
4139
4160
|
endedAt: null,
|
|
4140
4161
|
status: "active",
|
|
4141
|
-
costCents: 0
|
|
4162
|
+
costCents: 0,
|
|
4163
|
+
numTurns: 0
|
|
4142
4164
|
});
|
|
4143
4165
|
this.branchName = extractBranchFromDescription(card.description);
|
|
4144
4166
|
const localMode = !this.branchName;
|
|
@@ -4309,7 +4331,7 @@ class ReviewWorker {
|
|
|
4309
4331
|
}
|
|
4310
4332
|
if (this.runId) {
|
|
4311
4333
|
try {
|
|
4312
|
-
await this.stateStore.endRun(this.runId, this.state === "error" ? "paused" : "completed");
|
|
4334
|
+
await this.stateStore.endRun(this.runId, this.state === "error" ? "paused" : "completed", this.endLedger());
|
|
4313
4335
|
} catch {}
|
|
4314
4336
|
}
|
|
4315
4337
|
} finally {
|
|
@@ -4318,7 +4340,7 @@ class ReviewWorker {
|
|
|
4318
4340
|
const run = this.stateStore.getRun(this.runId);
|
|
4319
4341
|
if (run && run.endedAt === null) {
|
|
4320
4342
|
const status = this.timedOut ? "failed" : this.state === "error" || this.aborted ? "paused" : "completed";
|
|
4321
|
-
await this.stateStore.endRun(this.runId, status);
|
|
4343
|
+
await this.stateStore.endRun(this.runId, status, this.endLedger());
|
|
4322
4344
|
}
|
|
4323
4345
|
} catch {}
|
|
4324
4346
|
}
|
|
@@ -4989,6 +5011,8 @@ class Worker {
|
|
|
4989
5011
|
verificationFailed = false;
|
|
4990
5012
|
sessionId = null;
|
|
4991
5013
|
runId = null;
|
|
5014
|
+
runCostCents = 0;
|
|
5015
|
+
runTurns = 0;
|
|
4992
5016
|
constructor(id, config, client, agentId, onDone, workspaceId, projectId, stateStore, onCardCompleted, onApiError) {
|
|
4993
5017
|
this.config = config;
|
|
4994
5018
|
this.client = client;
|
|
@@ -5041,10 +5065,20 @@ class Worker {
|
|
|
5041
5065
|
get isActive() {
|
|
5042
5066
|
return this.state === "preparing" || this.state === "planning" || this.state === "running" || this.state === "verifying" || this.state === "completing";
|
|
5043
5067
|
}
|
|
5068
|
+
get costCents() {
|
|
5069
|
+
const live = this.progressTracker?.stats.cost;
|
|
5070
|
+
const liveCents = live ? Math.round(live.totalCostUsd * 100) : 0;
|
|
5071
|
+
return this.runCostCents + liveCents;
|
|
5072
|
+
}
|
|
5073
|
+
runLedger() {
|
|
5074
|
+
return { costCents: this.runCostCents, numTurns: this.runTurns };
|
|
5075
|
+
}
|
|
5044
5076
|
async run(card, column, labels, subtasks) {
|
|
5045
5077
|
this.aborted = false;
|
|
5046
5078
|
this.timedOut = false;
|
|
5047
5079
|
this.verificationFailed = false;
|
|
5080
|
+
this.runCostCents = 0;
|
|
5081
|
+
this.runTurns = 0;
|
|
5048
5082
|
this.cardId = card.id;
|
|
5049
5083
|
this.startedAt = Date.now();
|
|
5050
5084
|
this.runId = newRunId();
|
|
@@ -5069,7 +5103,8 @@ class Worker {
|
|
|
5069
5103
|
lastHeartbeatAt: this.startedAt,
|
|
5070
5104
|
endedAt: null,
|
|
5071
5105
|
status: "active",
|
|
5072
|
-
costCents: 0
|
|
5106
|
+
costCents: 0,
|
|
5107
|
+
numTurns: 0
|
|
5073
5108
|
});
|
|
5074
5109
|
const { session } = await this.client.startAgentSession(card.id, {
|
|
5075
5110
|
agentIdentifier: agentIdentifier(this.id),
|
|
@@ -5185,7 +5220,10 @@ class Worker {
|
|
|
5185
5220
|
}
|
|
5186
5221
|
if (this.runId) {
|
|
5187
5222
|
try {
|
|
5188
|
-
await this.stateStore.endRun(this.runId, "failed",
|
|
5223
|
+
await this.stateStore.endRun(this.runId, "failed", {
|
|
5224
|
+
errorMessage: errClass.kind ?? msg,
|
|
5225
|
+
...this.runLedger()
|
|
5226
|
+
});
|
|
5189
5227
|
} catch {}
|
|
5190
5228
|
if (apiError) {
|
|
5191
5229
|
await this.stateStore.decrementAttempt(card.id);
|
|
@@ -5197,7 +5235,7 @@ class Worker {
|
|
|
5197
5235
|
const succeeded = this.runId && this.state !== "error" && !this.aborted && !this.verificationFailed;
|
|
5198
5236
|
if (succeeded) {
|
|
5199
5237
|
try {
|
|
5200
|
-
await this.stateStore.endRun(this.runId, "completed");
|
|
5238
|
+
await this.stateStore.endRun(this.runId, "completed", this.runLedger());
|
|
5201
5239
|
} catch {}
|
|
5202
5240
|
await this.recordOutcome(card.id, "success");
|
|
5203
5241
|
} else if (this.runId && this.timedOut) {
|
|
@@ -5223,16 +5261,25 @@ class Worker {
|
|
|
5223
5261
|
log.error(this.tag, `timeout transition failed on #${card.short_id}: ${tErr instanceof TransitionError ? tErr.detail : tErr}`);
|
|
5224
5262
|
}
|
|
5225
5263
|
try {
|
|
5226
|
-
await this.stateStore.endRun(this.runId, "failed",
|
|
5264
|
+
await this.stateStore.endRun(this.runId, "failed", {
|
|
5265
|
+
errorMessage: "timeout",
|
|
5266
|
+
...this.runLedger()
|
|
5267
|
+
});
|
|
5227
5268
|
} catch {}
|
|
5228
5269
|
await this.recordOutcome(card.id, "failure");
|
|
5229
5270
|
} else if (this.runId && this.aborted) {
|
|
5230
5271
|
try {
|
|
5231
|
-
await this.stateStore.endRun(this.runId, "paused",
|
|
5272
|
+
await this.stateStore.endRun(this.runId, "paused", {
|
|
5273
|
+
errorMessage: "cancelled",
|
|
5274
|
+
...this.runLedger()
|
|
5275
|
+
});
|
|
5232
5276
|
} catch {}
|
|
5233
5277
|
} else if (this.runId && this.verificationFailed) {
|
|
5234
5278
|
try {
|
|
5235
|
-
await this.stateStore.endRun(this.runId, "paused",
|
|
5279
|
+
await this.stateStore.endRun(this.runId, "paused", {
|
|
5280
|
+
errorMessage: "verification",
|
|
5281
|
+
...this.runLedger()
|
|
5282
|
+
});
|
|
5236
5283
|
} catch {}
|
|
5237
5284
|
await this.recordOutcome(card.id, "failure");
|
|
5238
5285
|
}
|
|
@@ -5511,6 +5558,11 @@ class Worker {
|
|
|
5511
5558
|
this.process.on("close", (code) => {
|
|
5512
5559
|
this.process = null;
|
|
5513
5560
|
this.lastSessionStats = this.progressTracker?.stats;
|
|
5561
|
+
const spawnCost = this.lastSessionStats?.cost;
|
|
5562
|
+
if (spawnCost) {
|
|
5563
|
+
this.runCostCents += Math.round(spawnCost.totalCostUsd * 100);
|
|
5564
|
+
this.runTurns += spawnCost.numTurns;
|
|
5565
|
+
}
|
|
5514
5566
|
this.progressTracker?.flushFinal();
|
|
5515
5567
|
this.progressTracker?.stop();
|
|
5516
5568
|
this.progressTracker = null;
|
|
@@ -5558,6 +5610,8 @@ class Worker {
|
|
|
5558
5610
|
this.startedAt = null;
|
|
5559
5611
|
this.runId = null;
|
|
5560
5612
|
this.sessionId = null;
|
|
5613
|
+
this.runCostCents = 0;
|
|
5614
|
+
this.runTurns = 0;
|
|
5561
5615
|
}
|
|
5562
5616
|
}
|
|
5563
5617
|
var TAG23 = "worker", CANCEL_SIGINT_TIMEOUT2 = 30000, CANCEL_SIGTERM_TIMEOUT2 = 1e4, PLAN_ALLOWED_TOOLS = "Read,Grep,Glob,mcp__harmony__*", IMPLEMENT_ALLOWED_TOOLS = "Bash,Read,Write,Edit,Glob,Grep,Agent,mcp__harmony__*", PLAN_PHASE_TIMEOUT;
|
|
@@ -5780,7 +5834,8 @@ class Pool {
|
|
|
5780
5834
|
cardId: w.cardId,
|
|
5781
5835
|
cardShortId: null,
|
|
5782
5836
|
startedAt: w.startedAt,
|
|
5783
|
-
branchName: w.branchName
|
|
5837
|
+
branchName: w.branchName,
|
|
5838
|
+
costCents: w.costCents
|
|
5784
5839
|
});
|
|
5785
5840
|
}
|
|
5786
5841
|
for (const w of this.reviewWorkers) {
|
|
@@ -5791,7 +5846,8 @@ class Pool {
|
|
|
5791
5846
|
cardId: w.cardId,
|
|
5792
5847
|
cardShortId: null,
|
|
5793
5848
|
startedAt: w.startedAt,
|
|
5794
|
-
branchName: w.branchName
|
|
5849
|
+
branchName: w.branchName,
|
|
5850
|
+
costCents: w.costCents
|
|
5795
5851
|
});
|
|
5796
5852
|
}
|
|
5797
5853
|
return out;
|
|
@@ -6018,7 +6074,9 @@ async function recoverRun(run, store, client, config, outcome) {
|
|
|
6018
6074
|
}
|
|
6019
6075
|
}
|
|
6020
6076
|
try {
|
|
6021
|
-
await store.endRun(run.runId, "orphaned",
|
|
6077
|
+
await store.endRun(run.runId, "orphaned", {
|
|
6078
|
+
errorMessage: "recovered after daemon restart"
|
|
6079
|
+
});
|
|
6022
6080
|
} catch (err) {
|
|
6023
6081
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6024
6082
|
outcome.errors.push(`endRun: ${msg}`);
|
|
@@ -7182,14 +7240,16 @@ function printStatus(body) {
|
|
|
7182
7240
|
const uptime = formatDuration(body.uptimeMs);
|
|
7183
7241
|
out.write(`daemon ${body.daemonId} (pid ${body.daemonPid}, up ${uptime})
|
|
7184
7242
|
`);
|
|
7185
|
-
|
|
7243
|
+
const activeCents = body.workers.reduce((sum, w) => sum + (w.costCents ?? 0), 0);
|
|
7244
|
+
out.write(`budget $${(body.budget.todayCents / 100).toFixed(2)} / $${(body.budget.dailyCapCents / 100).toFixed(2)} today · $${(activeCents / 100).toFixed(2)} in-flight
|
|
7186
7245
|
`);
|
|
7187
7246
|
out.write(`workers (${body.workers.length})
|
|
7188
7247
|
`);
|
|
7189
7248
|
for (const w of body.workers) {
|
|
7190
7249
|
const card = w.cardId ? ` card=${w.cardId}` : "";
|
|
7191
7250
|
const br = w.branchName ? ` branch=${w.branchName}` : "";
|
|
7192
|
-
|
|
7251
|
+
const spend = w.costCents ? ` $${(w.costCents / 100).toFixed(2)}` : "";
|
|
7252
|
+
out.write(` #${w.id} ${w.pipeline.padEnd(9)} ${w.state}${card}${br}${spend}
|
|
7193
7253
|
`);
|
|
7194
7254
|
}
|
|
7195
7255
|
out.write(`impl queue (${body.implQueue.length})
|
package/dist/index.js
CHANGED
|
@@ -2317,7 +2317,8 @@ function buildTokenPayload(stats) {
|
|
|
2317
2317
|
outputTokens: stats.cost.totalOutputTokens,
|
|
2318
2318
|
cacheCreationInputTokens: stats.cost.totalCacheCreationInputTokens,
|
|
2319
2319
|
cacheReadInputTokens: stats.cost.totalCacheReadInputTokens,
|
|
2320
|
-
modelName: stats.cost.modelName
|
|
2320
|
+
modelName: stats.cost.modelName,
|
|
2321
|
+
numTurns: stats.cost.numTurns
|
|
2321
2322
|
};
|
|
2322
2323
|
}
|
|
2323
2324
|
async function runCompletion(client, card, branchName, worktreePath, config, workerId, sessionStats, workspaceId, agentSessionId, stateStore, onMovedToCompletion) {
|
|
@@ -2903,7 +2904,8 @@ class ProgressTracker {
|
|
|
2903
2904
|
outputTokens: this.lastCost?.totalOutputTokens ?? 0,
|
|
2904
2905
|
cacheCreationInputTokens: this.lastCost?.totalCacheCreationInputTokens ?? 0,
|
|
2905
2906
|
cacheReadInputTokens: this.lastCost?.totalCacheReadInputTokens ?? 0,
|
|
2906
|
-
modelName: this.lastCost?.modelName
|
|
2907
|
+
modelName: this.lastCost?.modelName,
|
|
2908
|
+
numTurns: this.lastCost?.numTurns ?? 0
|
|
2907
2909
|
}).catch((err) => {
|
|
2908
2910
|
log.warn(TAG14, `Failed to send progress update: ${err}`);
|
|
2909
2911
|
});
|
|
@@ -3674,13 +3676,19 @@ class StateStore {
|
|
|
3674
3676
|
heartbeat(runId) {
|
|
3675
3677
|
return this.updateRun(runId, { lastHeartbeatAt: Date.now() });
|
|
3676
3678
|
}
|
|
3677
|
-
endRun(runId, status,
|
|
3679
|
+
endRun(runId, status, opts = {}) {
|
|
3678
3680
|
const patch = {
|
|
3679
3681
|
status,
|
|
3680
3682
|
endedAt: Date.now()
|
|
3681
3683
|
};
|
|
3682
|
-
if (errorMessage !== undefined)
|
|
3683
|
-
patch.errorMessage = errorMessage;
|
|
3684
|
+
if (opts.errorMessage !== undefined)
|
|
3685
|
+
patch.errorMessage = opts.errorMessage;
|
|
3686
|
+
if (opts.costCents !== undefined && opts.costCents > 0) {
|
|
3687
|
+
patch.costCents = opts.costCents;
|
|
3688
|
+
}
|
|
3689
|
+
if (opts.numTurns !== undefined && opts.numTurns > 0) {
|
|
3690
|
+
patch.numTurns = opts.numTurns;
|
|
3691
|
+
}
|
|
3684
3692
|
return this.updateRun(runId, patch);
|
|
3685
3693
|
}
|
|
3686
3694
|
getRun(runId) {
|
|
@@ -4112,6 +4120,19 @@ class ReviewWorker {
|
|
|
4112
4120
|
get isActive() {
|
|
4113
4121
|
return this.state === "preparing" || this.state === "running" || this.state === "verifying" || this.state === "completing";
|
|
4114
4122
|
}
|
|
4123
|
+
get costCents() {
|
|
4124
|
+
const cost = (this.progressTracker?.stats ?? this.lastSessionStats)?.cost;
|
|
4125
|
+
return cost ? Math.round(cost.totalCostUsd * 100) : 0;
|
|
4126
|
+
}
|
|
4127
|
+
endLedger() {
|
|
4128
|
+
const cost = (this.lastSessionStats ?? this.progressTracker?.stats)?.cost;
|
|
4129
|
+
if (!cost)
|
|
4130
|
+
return { costCents: 0, numTurns: 0 };
|
|
4131
|
+
return {
|
|
4132
|
+
costCents: Math.round(cost.totalCostUsd * 100),
|
|
4133
|
+
numTurns: cost.numTurns
|
|
4134
|
+
};
|
|
4135
|
+
}
|
|
4115
4136
|
async run(card, column, labels, subtasks) {
|
|
4116
4137
|
this.aborted = false;
|
|
4117
4138
|
this.timedOut = false;
|
|
@@ -4137,7 +4158,8 @@ class ReviewWorker {
|
|
|
4137
4158
|
lastHeartbeatAt: this.startedAt,
|
|
4138
4159
|
endedAt: null,
|
|
4139
4160
|
status: "active",
|
|
4140
|
-
costCents: 0
|
|
4161
|
+
costCents: 0,
|
|
4162
|
+
numTurns: 0
|
|
4141
4163
|
});
|
|
4142
4164
|
this.branchName = extractBranchFromDescription(card.description);
|
|
4143
4165
|
const localMode = !this.branchName;
|
|
@@ -4308,7 +4330,7 @@ class ReviewWorker {
|
|
|
4308
4330
|
}
|
|
4309
4331
|
if (this.runId) {
|
|
4310
4332
|
try {
|
|
4311
|
-
await this.stateStore.endRun(this.runId, this.state === "error" ? "paused" : "completed");
|
|
4333
|
+
await this.stateStore.endRun(this.runId, this.state === "error" ? "paused" : "completed", this.endLedger());
|
|
4312
4334
|
} catch {}
|
|
4313
4335
|
}
|
|
4314
4336
|
} finally {
|
|
@@ -4317,7 +4339,7 @@ class ReviewWorker {
|
|
|
4317
4339
|
const run = this.stateStore.getRun(this.runId);
|
|
4318
4340
|
if (run && run.endedAt === null) {
|
|
4319
4341
|
const status = this.timedOut ? "failed" : this.state === "error" || this.aborted ? "paused" : "completed";
|
|
4320
|
-
await this.stateStore.endRun(this.runId, status);
|
|
4342
|
+
await this.stateStore.endRun(this.runId, status, this.endLedger());
|
|
4321
4343
|
}
|
|
4322
4344
|
} catch {}
|
|
4323
4345
|
}
|
|
@@ -4988,6 +5010,8 @@ class Worker {
|
|
|
4988
5010
|
verificationFailed = false;
|
|
4989
5011
|
sessionId = null;
|
|
4990
5012
|
runId = null;
|
|
5013
|
+
runCostCents = 0;
|
|
5014
|
+
runTurns = 0;
|
|
4991
5015
|
constructor(id, config, client, agentId, onDone, workspaceId, projectId, stateStore, onCardCompleted, onApiError) {
|
|
4992
5016
|
this.config = config;
|
|
4993
5017
|
this.client = client;
|
|
@@ -5040,10 +5064,20 @@ class Worker {
|
|
|
5040
5064
|
get isActive() {
|
|
5041
5065
|
return this.state === "preparing" || this.state === "planning" || this.state === "running" || this.state === "verifying" || this.state === "completing";
|
|
5042
5066
|
}
|
|
5067
|
+
get costCents() {
|
|
5068
|
+
const live = this.progressTracker?.stats.cost;
|
|
5069
|
+
const liveCents = live ? Math.round(live.totalCostUsd * 100) : 0;
|
|
5070
|
+
return this.runCostCents + liveCents;
|
|
5071
|
+
}
|
|
5072
|
+
runLedger() {
|
|
5073
|
+
return { costCents: this.runCostCents, numTurns: this.runTurns };
|
|
5074
|
+
}
|
|
5043
5075
|
async run(card, column, labels, subtasks) {
|
|
5044
5076
|
this.aborted = false;
|
|
5045
5077
|
this.timedOut = false;
|
|
5046
5078
|
this.verificationFailed = false;
|
|
5079
|
+
this.runCostCents = 0;
|
|
5080
|
+
this.runTurns = 0;
|
|
5047
5081
|
this.cardId = card.id;
|
|
5048
5082
|
this.startedAt = Date.now();
|
|
5049
5083
|
this.runId = newRunId();
|
|
@@ -5068,7 +5102,8 @@ class Worker {
|
|
|
5068
5102
|
lastHeartbeatAt: this.startedAt,
|
|
5069
5103
|
endedAt: null,
|
|
5070
5104
|
status: "active",
|
|
5071
|
-
costCents: 0
|
|
5105
|
+
costCents: 0,
|
|
5106
|
+
numTurns: 0
|
|
5072
5107
|
});
|
|
5073
5108
|
const { session } = await this.client.startAgentSession(card.id, {
|
|
5074
5109
|
agentIdentifier: agentIdentifier(this.id),
|
|
@@ -5184,7 +5219,10 @@ class Worker {
|
|
|
5184
5219
|
}
|
|
5185
5220
|
if (this.runId) {
|
|
5186
5221
|
try {
|
|
5187
|
-
await this.stateStore.endRun(this.runId, "failed",
|
|
5222
|
+
await this.stateStore.endRun(this.runId, "failed", {
|
|
5223
|
+
errorMessage: errClass.kind ?? msg,
|
|
5224
|
+
...this.runLedger()
|
|
5225
|
+
});
|
|
5188
5226
|
} catch {}
|
|
5189
5227
|
if (apiError) {
|
|
5190
5228
|
await this.stateStore.decrementAttempt(card.id);
|
|
@@ -5196,7 +5234,7 @@ class Worker {
|
|
|
5196
5234
|
const succeeded = this.runId && this.state !== "error" && !this.aborted && !this.verificationFailed;
|
|
5197
5235
|
if (succeeded) {
|
|
5198
5236
|
try {
|
|
5199
|
-
await this.stateStore.endRun(this.runId, "completed");
|
|
5237
|
+
await this.stateStore.endRun(this.runId, "completed", this.runLedger());
|
|
5200
5238
|
} catch {}
|
|
5201
5239
|
await this.recordOutcome(card.id, "success");
|
|
5202
5240
|
} else if (this.runId && this.timedOut) {
|
|
@@ -5222,16 +5260,25 @@ class Worker {
|
|
|
5222
5260
|
log.error(this.tag, `timeout transition failed on #${card.short_id}: ${tErr instanceof TransitionError ? tErr.detail : tErr}`);
|
|
5223
5261
|
}
|
|
5224
5262
|
try {
|
|
5225
|
-
await this.stateStore.endRun(this.runId, "failed",
|
|
5263
|
+
await this.stateStore.endRun(this.runId, "failed", {
|
|
5264
|
+
errorMessage: "timeout",
|
|
5265
|
+
...this.runLedger()
|
|
5266
|
+
});
|
|
5226
5267
|
} catch {}
|
|
5227
5268
|
await this.recordOutcome(card.id, "failure");
|
|
5228
5269
|
} else if (this.runId && this.aborted) {
|
|
5229
5270
|
try {
|
|
5230
|
-
await this.stateStore.endRun(this.runId, "paused",
|
|
5271
|
+
await this.stateStore.endRun(this.runId, "paused", {
|
|
5272
|
+
errorMessage: "cancelled",
|
|
5273
|
+
...this.runLedger()
|
|
5274
|
+
});
|
|
5231
5275
|
} catch {}
|
|
5232
5276
|
} else if (this.runId && this.verificationFailed) {
|
|
5233
5277
|
try {
|
|
5234
|
-
await this.stateStore.endRun(this.runId, "paused",
|
|
5278
|
+
await this.stateStore.endRun(this.runId, "paused", {
|
|
5279
|
+
errorMessage: "verification",
|
|
5280
|
+
...this.runLedger()
|
|
5281
|
+
});
|
|
5235
5282
|
} catch {}
|
|
5236
5283
|
await this.recordOutcome(card.id, "failure");
|
|
5237
5284
|
}
|
|
@@ -5510,6 +5557,11 @@ class Worker {
|
|
|
5510
5557
|
this.process.on("close", (code) => {
|
|
5511
5558
|
this.process = null;
|
|
5512
5559
|
this.lastSessionStats = this.progressTracker?.stats;
|
|
5560
|
+
const spawnCost = this.lastSessionStats?.cost;
|
|
5561
|
+
if (spawnCost) {
|
|
5562
|
+
this.runCostCents += Math.round(spawnCost.totalCostUsd * 100);
|
|
5563
|
+
this.runTurns += spawnCost.numTurns;
|
|
5564
|
+
}
|
|
5513
5565
|
this.progressTracker?.flushFinal();
|
|
5514
5566
|
this.progressTracker?.stop();
|
|
5515
5567
|
this.progressTracker = null;
|
|
@@ -5557,6 +5609,8 @@ class Worker {
|
|
|
5557
5609
|
this.startedAt = null;
|
|
5558
5610
|
this.runId = null;
|
|
5559
5611
|
this.sessionId = null;
|
|
5612
|
+
this.runCostCents = 0;
|
|
5613
|
+
this.runTurns = 0;
|
|
5560
5614
|
}
|
|
5561
5615
|
}
|
|
5562
5616
|
var TAG23 = "worker", CANCEL_SIGINT_TIMEOUT2 = 30000, CANCEL_SIGTERM_TIMEOUT2 = 1e4, PLAN_ALLOWED_TOOLS = "Read,Grep,Glob,mcp__harmony__*", IMPLEMENT_ALLOWED_TOOLS = "Bash,Read,Write,Edit,Glob,Grep,Agent,mcp__harmony__*", PLAN_PHASE_TIMEOUT;
|
|
@@ -5779,7 +5833,8 @@ class Pool {
|
|
|
5779
5833
|
cardId: w.cardId,
|
|
5780
5834
|
cardShortId: null,
|
|
5781
5835
|
startedAt: w.startedAt,
|
|
5782
|
-
branchName: w.branchName
|
|
5836
|
+
branchName: w.branchName,
|
|
5837
|
+
costCents: w.costCents
|
|
5783
5838
|
});
|
|
5784
5839
|
}
|
|
5785
5840
|
for (const w of this.reviewWorkers) {
|
|
@@ -5790,7 +5845,8 @@ class Pool {
|
|
|
5790
5845
|
cardId: w.cardId,
|
|
5791
5846
|
cardShortId: null,
|
|
5792
5847
|
startedAt: w.startedAt,
|
|
5793
|
-
branchName: w.branchName
|
|
5848
|
+
branchName: w.branchName,
|
|
5849
|
+
costCents: w.costCents
|
|
5794
5850
|
});
|
|
5795
5851
|
}
|
|
5796
5852
|
return out;
|
|
@@ -6017,7 +6073,9 @@ async function recoverRun(run, store, client, config, outcome) {
|
|
|
6017
6073
|
}
|
|
6018
6074
|
}
|
|
6019
6075
|
try {
|
|
6020
|
-
await store.endRun(run.runId, "orphaned",
|
|
6076
|
+
await store.endRun(run.runId, "orphaned", {
|
|
6077
|
+
errorMessage: "recovered after daemon restart"
|
|
6078
|
+
});
|
|
6021
6079
|
} catch (err) {
|
|
6022
6080
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6023
6081
|
outcome.errors.push(`endRun: ${msg}`);
|