@gethmy/mcp 2.13.0 → 2.13.1
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 +54 -12
- package/dist/index.js +54 -12
- package/package.json +1 -1
- package/src/server.ts +115 -31
package/dist/cli.js
CHANGED
|
@@ -3529,6 +3529,45 @@ function parseLabelList(raw) {
|
|
|
3529
3529
|
}
|
|
3530
3530
|
return;
|
|
3531
3531
|
}
|
|
3532
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3533
|
+
function requireStringArg(raw, field, opts = {}) {
|
|
3534
|
+
let value;
|
|
3535
|
+
if (typeof raw === "string")
|
|
3536
|
+
value = raw.trim();
|
|
3537
|
+
else if (typeof raw === "number" || typeof raw === "boolean")
|
|
3538
|
+
value = String(raw);
|
|
3539
|
+
else
|
|
3540
|
+
throw new Error(`${field} is required and must be a string (received ${raw === undefined || raw === null ? "nothing" : typeof raw}).`);
|
|
3541
|
+
if (value.length === 0)
|
|
3542
|
+
throw new Error(`${field} is required and must not be empty.`);
|
|
3543
|
+
if (opts.max && value.length > opts.max)
|
|
3544
|
+
throw new Error(`${field} must be at most ${opts.max} characters (received ${value.length}).`);
|
|
3545
|
+
return value;
|
|
3546
|
+
}
|
|
3547
|
+
function requireUuidArg(raw, field) {
|
|
3548
|
+
const value = requireStringArg(raw, field);
|
|
3549
|
+
if (!UUID_RE.test(value))
|
|
3550
|
+
throw new Error(`${field} must be a valid UUID (received "${value}").`);
|
|
3551
|
+
return value;
|
|
3552
|
+
}
|
|
3553
|
+
function optionalPercentArg(raw, field) {
|
|
3554
|
+
if (raw === undefined || raw === null)
|
|
3555
|
+
return;
|
|
3556
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
3557
|
+
if (!Number.isFinite(n))
|
|
3558
|
+
throw new Error(`${field} must be a number between 0 and 100.`);
|
|
3559
|
+
if (n < 0 || n > 100)
|
|
3560
|
+
throw new Error(`${field} must be between 0 and 100 (received ${n}).`);
|
|
3561
|
+
return n;
|
|
3562
|
+
}
|
|
3563
|
+
function optionalNonNegativeNumberArg(raw, field) {
|
|
3564
|
+
if (raw === undefined || raw === null)
|
|
3565
|
+
return;
|
|
3566
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
3567
|
+
if (!Number.isFinite(n) || n < 0)
|
|
3568
|
+
throw new Error(`${field} must be a non-negative number.`);
|
|
3569
|
+
return n;
|
|
3570
|
+
}
|
|
3532
3571
|
function initMemorySession(cardId, agentIdentifier, agentName, agentSessionId) {
|
|
3533
3572
|
memorySessions.set(cardId, {
|
|
3534
3573
|
cardId,
|
|
@@ -5376,7 +5415,6 @@ function registerHandlers(server, deps) {
|
|
|
5376
5415
|
const { name, arguments: args } = request.params;
|
|
5377
5416
|
const toolArgs = args || {};
|
|
5378
5417
|
const cardIdArg = toolArgs.cardId;
|
|
5379
|
-
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
5380
5418
|
if (cardIdArg && UUID_RE.test(cardIdArg) && deps.isConfigured()) {
|
|
5381
5419
|
const isAutoStartTrigger = AUTO_START_TRIGGERS.has(name);
|
|
5382
5420
|
const cv = server.getClientVersion?.();
|
|
@@ -6042,9 +6080,11 @@ async function handleToolCall(name, args, deps) {
|
|
|
6042
6080
|
return { success: true, ...result };
|
|
6043
6081
|
}
|
|
6044
6082
|
case "harmony_start_agent_session": {
|
|
6045
|
-
const cardId =
|
|
6046
|
-
const agentIdentifier =
|
|
6047
|
-
const agentName =
|
|
6083
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
6084
|
+
const agentIdentifier = requireStringArg(args.agentIdentifier, "agentIdentifier", { max: 100 });
|
|
6085
|
+
const agentName = requireStringArg(args.agentName, "agentName", {
|
|
6086
|
+
max: 100
|
|
6087
|
+
});
|
|
6048
6088
|
const moveToColumn = args.moveToColumn;
|
|
6049
6089
|
const addLabels = parseLabelList(args.addLabels);
|
|
6050
6090
|
let movedTo = null;
|
|
@@ -6105,7 +6145,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
6105
6145
|
agentName,
|
|
6106
6146
|
status: "working",
|
|
6107
6147
|
currentTask: args.currentTask,
|
|
6108
|
-
estimatedMinutesRemaining: args.estimatedMinutesRemaining,
|
|
6148
|
+
estimatedMinutesRemaining: optionalNonNegativeNumberArg(args.estimatedMinutesRemaining, "estimatedMinutesRemaining"),
|
|
6109
6149
|
steerable: args.steerable === true || args.steerable === "true" ? true : undefined
|
|
6110
6150
|
});
|
|
6111
6151
|
markExplicit(cardId, {
|
|
@@ -6125,10 +6165,12 @@ async function handleToolCall(name, args, deps) {
|
|
|
6125
6165
|
};
|
|
6126
6166
|
}
|
|
6127
6167
|
case "harmony_update_agent_progress": {
|
|
6128
|
-
const cardId =
|
|
6129
|
-
const agentIdentifier =
|
|
6130
|
-
const agentName =
|
|
6131
|
-
|
|
6168
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
6169
|
+
const agentIdentifier = requireStringArg(args.agentIdentifier, "agentIdentifier", { max: 100 });
|
|
6170
|
+
const agentName = requireStringArg(args.agentName, "agentName", {
|
|
6171
|
+
max: 100
|
|
6172
|
+
});
|
|
6173
|
+
const progressPercent = optionalPercentArg(args.progressPercent, "progressPercent");
|
|
6132
6174
|
const callerActions = args.actions;
|
|
6133
6175
|
const now = new Date().toISOString();
|
|
6134
6176
|
const callerRecentActions = [
|
|
@@ -6153,17 +6195,17 @@ async function handleToolCall(name, args, deps) {
|
|
|
6153
6195
|
progressPercent,
|
|
6154
6196
|
currentTask: args.currentTask,
|
|
6155
6197
|
blockers: args.blockers,
|
|
6156
|
-
estimatedMinutesRemaining: args.estimatedMinutesRemaining,
|
|
6198
|
+
estimatedMinutesRemaining: optionalNonNegativeNumberArg(args.estimatedMinutesRemaining, "estimatedMinutesRemaining"),
|
|
6157
6199
|
...mergedRecentActions && { recentActions: mergedRecentActions },
|
|
6158
6200
|
...runActivity.length > 0 && { runActivity }
|
|
6159
6201
|
});
|
|
6160
6202
|
return { success: true, midSessionLearnings: 0, ...result };
|
|
6161
6203
|
}
|
|
6162
6204
|
case "harmony_end_agent_session": {
|
|
6163
|
-
const cardId =
|
|
6205
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
6164
6206
|
const moveToColumn = args.moveToColumn;
|
|
6165
6207
|
const sessionStatus = args.status || "completed";
|
|
6166
|
-
const endProgressPercent = args.progressPercent
|
|
6208
|
+
const endProgressPercent = optionalPercentArg(args.progressPercent, "progressPercent");
|
|
6167
6209
|
await flushMemoryActions(client3, cardId);
|
|
6168
6210
|
cleanupMemorySession(cardId);
|
|
6169
6211
|
let result = { session: null };
|
package/dist/index.js
CHANGED
|
@@ -3524,6 +3524,45 @@ function parseLabelList(raw) {
|
|
|
3524
3524
|
}
|
|
3525
3525
|
return;
|
|
3526
3526
|
}
|
|
3527
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3528
|
+
function requireStringArg(raw, field, opts = {}) {
|
|
3529
|
+
let value;
|
|
3530
|
+
if (typeof raw === "string")
|
|
3531
|
+
value = raw.trim();
|
|
3532
|
+
else if (typeof raw === "number" || typeof raw === "boolean")
|
|
3533
|
+
value = String(raw);
|
|
3534
|
+
else
|
|
3535
|
+
throw new Error(`${field} is required and must be a string (received ${raw === undefined || raw === null ? "nothing" : typeof raw}).`);
|
|
3536
|
+
if (value.length === 0)
|
|
3537
|
+
throw new Error(`${field} is required and must not be empty.`);
|
|
3538
|
+
if (opts.max && value.length > opts.max)
|
|
3539
|
+
throw new Error(`${field} must be at most ${opts.max} characters (received ${value.length}).`);
|
|
3540
|
+
return value;
|
|
3541
|
+
}
|
|
3542
|
+
function requireUuidArg(raw, field) {
|
|
3543
|
+
const value = requireStringArg(raw, field);
|
|
3544
|
+
if (!UUID_RE.test(value))
|
|
3545
|
+
throw new Error(`${field} must be a valid UUID (received "${value}").`);
|
|
3546
|
+
return value;
|
|
3547
|
+
}
|
|
3548
|
+
function optionalPercentArg(raw, field) {
|
|
3549
|
+
if (raw === undefined || raw === null)
|
|
3550
|
+
return;
|
|
3551
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
3552
|
+
if (!Number.isFinite(n))
|
|
3553
|
+
throw new Error(`${field} must be a number between 0 and 100.`);
|
|
3554
|
+
if (n < 0 || n > 100)
|
|
3555
|
+
throw new Error(`${field} must be between 0 and 100 (received ${n}).`);
|
|
3556
|
+
return n;
|
|
3557
|
+
}
|
|
3558
|
+
function optionalNonNegativeNumberArg(raw, field) {
|
|
3559
|
+
if (raw === undefined || raw === null)
|
|
3560
|
+
return;
|
|
3561
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
3562
|
+
if (!Number.isFinite(n) || n < 0)
|
|
3563
|
+
throw new Error(`${field} must be a non-negative number.`);
|
|
3564
|
+
return n;
|
|
3565
|
+
}
|
|
3527
3566
|
function initMemorySession(cardId, agentIdentifier, agentName, agentSessionId) {
|
|
3528
3567
|
memorySessions.set(cardId, {
|
|
3529
3568
|
cardId,
|
|
@@ -5371,7 +5410,6 @@ function registerHandlers(server, deps) {
|
|
|
5371
5410
|
const { name, arguments: args } = request.params;
|
|
5372
5411
|
const toolArgs = args || {};
|
|
5373
5412
|
const cardIdArg = toolArgs.cardId;
|
|
5374
|
-
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
5375
5413
|
if (cardIdArg && UUID_RE.test(cardIdArg) && deps.isConfigured()) {
|
|
5376
5414
|
const isAutoStartTrigger = AUTO_START_TRIGGERS.has(name);
|
|
5377
5415
|
const cv = server.getClientVersion?.();
|
|
@@ -6037,9 +6075,11 @@ async function handleToolCall(name, args, deps) {
|
|
|
6037
6075
|
return { success: true, ...result };
|
|
6038
6076
|
}
|
|
6039
6077
|
case "harmony_start_agent_session": {
|
|
6040
|
-
const cardId =
|
|
6041
|
-
const agentIdentifier =
|
|
6042
|
-
const agentName =
|
|
6078
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
6079
|
+
const agentIdentifier = requireStringArg(args.agentIdentifier, "agentIdentifier", { max: 100 });
|
|
6080
|
+
const agentName = requireStringArg(args.agentName, "agentName", {
|
|
6081
|
+
max: 100
|
|
6082
|
+
});
|
|
6043
6083
|
const moveToColumn = args.moveToColumn;
|
|
6044
6084
|
const addLabels = parseLabelList(args.addLabels);
|
|
6045
6085
|
let movedTo = null;
|
|
@@ -6100,7 +6140,7 @@ async function handleToolCall(name, args, deps) {
|
|
|
6100
6140
|
agentName,
|
|
6101
6141
|
status: "working",
|
|
6102
6142
|
currentTask: args.currentTask,
|
|
6103
|
-
estimatedMinutesRemaining: args.estimatedMinutesRemaining,
|
|
6143
|
+
estimatedMinutesRemaining: optionalNonNegativeNumberArg(args.estimatedMinutesRemaining, "estimatedMinutesRemaining"),
|
|
6104
6144
|
steerable: args.steerable === true || args.steerable === "true" ? true : undefined
|
|
6105
6145
|
});
|
|
6106
6146
|
markExplicit(cardId, {
|
|
@@ -6120,10 +6160,12 @@ async function handleToolCall(name, args, deps) {
|
|
|
6120
6160
|
};
|
|
6121
6161
|
}
|
|
6122
6162
|
case "harmony_update_agent_progress": {
|
|
6123
|
-
const cardId =
|
|
6124
|
-
const agentIdentifier =
|
|
6125
|
-
const agentName =
|
|
6126
|
-
|
|
6163
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
6164
|
+
const agentIdentifier = requireStringArg(args.agentIdentifier, "agentIdentifier", { max: 100 });
|
|
6165
|
+
const agentName = requireStringArg(args.agentName, "agentName", {
|
|
6166
|
+
max: 100
|
|
6167
|
+
});
|
|
6168
|
+
const progressPercent = optionalPercentArg(args.progressPercent, "progressPercent");
|
|
6127
6169
|
const callerActions = args.actions;
|
|
6128
6170
|
const now = new Date().toISOString();
|
|
6129
6171
|
const callerRecentActions = [
|
|
@@ -6148,17 +6190,17 @@ async function handleToolCall(name, args, deps) {
|
|
|
6148
6190
|
progressPercent,
|
|
6149
6191
|
currentTask: args.currentTask,
|
|
6150
6192
|
blockers: args.blockers,
|
|
6151
|
-
estimatedMinutesRemaining: args.estimatedMinutesRemaining,
|
|
6193
|
+
estimatedMinutesRemaining: optionalNonNegativeNumberArg(args.estimatedMinutesRemaining, "estimatedMinutesRemaining"),
|
|
6152
6194
|
...mergedRecentActions && { recentActions: mergedRecentActions },
|
|
6153
6195
|
...runActivity.length > 0 && { runActivity }
|
|
6154
6196
|
});
|
|
6155
6197
|
return { success: true, midSessionLearnings: 0, ...result };
|
|
6156
6198
|
}
|
|
6157
6199
|
case "harmony_end_agent_session": {
|
|
6158
|
-
const cardId =
|
|
6200
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
6159
6201
|
const moveToColumn = args.moveToColumn;
|
|
6160
6202
|
const sessionStatus = args.status || "completed";
|
|
6161
|
-
const endProgressPercent = args.progressPercent
|
|
6203
|
+
const endProgressPercent = optionalPercentArg(args.progressPercent, "progressPercent");
|
|
6162
6204
|
await flushMemoryActions(client3, cardId);
|
|
6163
6205
|
cleanupMemorySession(cardId);
|
|
6164
6206
|
let result = { session: null };
|
package/package.json
CHANGED
package/src/server.ts
CHANGED
|
@@ -244,6 +244,86 @@ function parseLabelList(raw: unknown): string[] | undefined {
|
|
|
244
244
|
return undefined;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
const UUID_RE =
|
|
248
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Coerce + validate a required string argument from a (possibly lenient) MCP
|
|
252
|
+
* caller, throwing a clear, field-attributed error on failure.
|
|
253
|
+
*
|
|
254
|
+
* The agent-session tools previously parsed these with a bare
|
|
255
|
+
* `z.string().parse(args.foo)`. When the field was missing or arrived as a
|
|
256
|
+
* non-string, Zod surfaced an opaque root-level blob —
|
|
257
|
+
* `[{"expected":"string","received":"undefined","path":[],...}]` — that names
|
|
258
|
+
* neither the offending field nor the received value. To an agent that reads
|
|
259
|
+
* as "the tool rejects every argument shape with an `expected string` error"
|
|
260
|
+
* (card #530). Instead we name the field, report what we got, and (matching
|
|
261
|
+
* the `parseLabelList` philosophy for quirky clients) accept the
|
|
262
|
+
* number/boolean values some MCP clients emit by stringifying scalars.
|
|
263
|
+
*/
|
|
264
|
+
function requireStringArg(
|
|
265
|
+
raw: unknown,
|
|
266
|
+
field: string,
|
|
267
|
+
opts: { max?: number } = {},
|
|
268
|
+
): string {
|
|
269
|
+
let value: string;
|
|
270
|
+
if (typeof raw === "string") value = raw.trim();
|
|
271
|
+
else if (typeof raw === "number" || typeof raw === "boolean")
|
|
272
|
+
value = String(raw);
|
|
273
|
+
else
|
|
274
|
+
throw new Error(
|
|
275
|
+
`${field} is required and must be a string (received ${
|
|
276
|
+
raw === undefined || raw === null ? "nothing" : typeof raw
|
|
277
|
+
}).`,
|
|
278
|
+
);
|
|
279
|
+
if (value.length === 0)
|
|
280
|
+
throw new Error(`${field} is required and must not be empty.`);
|
|
281
|
+
if (opts.max && value.length > opts.max)
|
|
282
|
+
throw new Error(
|
|
283
|
+
`${field} must be at most ${opts.max} characters (received ${value.length}).`,
|
|
284
|
+
);
|
|
285
|
+
return value;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** Coerce + validate a required UUID argument with a field-named error. */
|
|
289
|
+
function requireUuidArg(raw: unknown, field: string): string {
|
|
290
|
+
const value = requireStringArg(raw, field);
|
|
291
|
+
if (!UUID_RE.test(value))
|
|
292
|
+
throw new Error(`${field} must be a valid UUID (received "${value}").`);
|
|
293
|
+
return value;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Coerce an optional 0–100 percentage. Accepts numeric strings (e.g. "50")
|
|
298
|
+
* because lenient MCP clients stringify scalar arguments; returns `undefined`
|
|
299
|
+
* when absent and throws a clear, field-named error when out of range.
|
|
300
|
+
*/
|
|
301
|
+
function optionalPercentArg(raw: unknown, field: string): number | undefined {
|
|
302
|
+
if (raw === undefined || raw === null) return undefined;
|
|
303
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
304
|
+
if (!Number.isFinite(n))
|
|
305
|
+
throw new Error(`${field} must be a number between 0 and 100.`);
|
|
306
|
+
if (n < 0 || n > 100)
|
|
307
|
+
throw new Error(`${field} must be between 0 and 100 (received ${n}).`);
|
|
308
|
+
return n;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Coerce an optional non-negative number argument (e.g.
|
|
313
|
+
* `estimatedMinutesRemaining`). Accepts numeric strings; returns `undefined`
|
|
314
|
+
* when absent so the field is omitted from the API payload entirely.
|
|
315
|
+
*/
|
|
316
|
+
function optionalNonNegativeNumberArg(
|
|
317
|
+
raw: unknown,
|
|
318
|
+
field: string,
|
|
319
|
+
): number | undefined {
|
|
320
|
+
if (raw === undefined || raw === null) return undefined;
|
|
321
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
322
|
+
if (!Number.isFinite(n) || n < 0)
|
|
323
|
+
throw new Error(`${field} must be a non-negative number.`);
|
|
324
|
+
return n;
|
|
325
|
+
}
|
|
326
|
+
|
|
247
327
|
function initMemorySession(
|
|
248
328
|
cardId: string,
|
|
249
329
|
agentIdentifier: string,
|
|
@@ -2369,8 +2449,6 @@ export function registerHandlers(server: Server, deps: ToolDeps): void {
|
|
|
2369
2449
|
// Auto-session pre-hook: track activity on card-related tools
|
|
2370
2450
|
const toolArgs = args || {};
|
|
2371
2451
|
const cardIdArg = toolArgs.cardId as string | undefined;
|
|
2372
|
-
const UUID_RE =
|
|
2373
|
-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2374
2452
|
if (cardIdArg && UUID_RE.test(cardIdArg) && deps.isConfigured()) {
|
|
2375
2453
|
const isAutoStartTrigger = AUTO_START_TRIGGERS.has(name);
|
|
2376
2454
|
// Resolve MCP client identity per request from the in-scope Server. The
|
|
@@ -3356,13 +3434,15 @@ async function handleToolCall(
|
|
|
3356
3434
|
|
|
3357
3435
|
// Agent context operations
|
|
3358
3436
|
case "harmony_start_agent_session": {
|
|
3359
|
-
const cardId =
|
|
3360
|
-
const agentIdentifier =
|
|
3361
|
-
.
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
const agentName =
|
|
3437
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
3438
|
+
const agentIdentifier = requireStringArg(
|
|
3439
|
+
args.agentIdentifier,
|
|
3440
|
+
"agentIdentifier",
|
|
3441
|
+
{ max: 100 },
|
|
3442
|
+
);
|
|
3443
|
+
const agentName = requireStringArg(args.agentName, "agentName", {
|
|
3444
|
+
max: 100,
|
|
3445
|
+
});
|
|
3366
3446
|
const moveToColumn = args.moveToColumn as string | undefined;
|
|
3367
3447
|
const addLabels = parseLabelList(args.addLabels);
|
|
3368
3448
|
|
|
@@ -3449,9 +3529,10 @@ async function handleToolCall(
|
|
|
3449
3529
|
agentName,
|
|
3450
3530
|
status: "working",
|
|
3451
3531
|
currentTask: args.currentTask as string | undefined,
|
|
3452
|
-
estimatedMinutesRemaining:
|
|
3453
|
-
|
|
3454
|
-
|
|
3532
|
+
estimatedMinutesRemaining: optionalNonNegativeNumberArg(
|
|
3533
|
+
args.estimatedMinutesRemaining,
|
|
3534
|
+
"estimatedMinutesRemaining",
|
|
3535
|
+
),
|
|
3455
3536
|
steerable:
|
|
3456
3537
|
args.steerable === true || args.steerable === "true"
|
|
3457
3538
|
? true
|
|
@@ -3482,17 +3563,19 @@ async function handleToolCall(
|
|
|
3482
3563
|
}
|
|
3483
3564
|
|
|
3484
3565
|
case "harmony_update_agent_progress": {
|
|
3485
|
-
const cardId =
|
|
3486
|
-
const agentIdentifier =
|
|
3487
|
-
.
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
const agentName =
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3566
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
3567
|
+
const agentIdentifier = requireStringArg(
|
|
3568
|
+
args.agentIdentifier,
|
|
3569
|
+
"agentIdentifier",
|
|
3570
|
+
{ max: 100 },
|
|
3571
|
+
);
|
|
3572
|
+
const agentName = requireStringArg(args.agentName, "agentName", {
|
|
3573
|
+
max: 100,
|
|
3574
|
+
});
|
|
3575
|
+
const progressPercent = optionalPercentArg(
|
|
3576
|
+
args.progressPercent,
|
|
3577
|
+
"progressPercent",
|
|
3578
|
+
);
|
|
3496
3579
|
// Convert actions parameter to recentActions format and merge with memory actions
|
|
3497
3580
|
const callerActions = args.actions as
|
|
3498
3581
|
| { description: string }[]
|
|
@@ -3535,9 +3618,10 @@ async function handleToolCall(
|
|
|
3535
3618
|
progressPercent,
|
|
3536
3619
|
currentTask: args.currentTask as string | undefined,
|
|
3537
3620
|
blockers: args.blockers as string[] | undefined,
|
|
3538
|
-
estimatedMinutesRemaining:
|
|
3539
|
-
|
|
3540
|
-
|
|
3621
|
+
estimatedMinutesRemaining: optionalNonNegativeNumberArg(
|
|
3622
|
+
args.estimatedMinutesRemaining,
|
|
3623
|
+
"estimatedMinutesRemaining",
|
|
3624
|
+
),
|
|
3541
3625
|
...(mergedRecentActions && { recentActions: mergedRecentActions }),
|
|
3542
3626
|
...(runActivity.length > 0 && { runActivity }),
|
|
3543
3627
|
});
|
|
@@ -3547,14 +3631,14 @@ async function handleToolCall(
|
|
|
3547
3631
|
}
|
|
3548
3632
|
|
|
3549
3633
|
case "harmony_end_agent_session": {
|
|
3550
|
-
const cardId =
|
|
3634
|
+
const cardId = requireUuidArg(args.cardId, "cardId");
|
|
3551
3635
|
const moveToColumn = args.moveToColumn as string | undefined;
|
|
3552
3636
|
const sessionStatus =
|
|
3553
3637
|
(args.status as "completed" | "paused") || "completed";
|
|
3554
|
-
const endProgressPercent =
|
|
3555
|
-
args.progressPercent
|
|
3556
|
-
|
|
3557
|
-
|
|
3638
|
+
const endProgressPercent = optionalPercentArg(
|
|
3639
|
+
args.progressPercent,
|
|
3640
|
+
"progressPercent",
|
|
3641
|
+
);
|
|
3558
3642
|
|
|
3559
3643
|
// Final flush of any pending memory actions before ending the session
|
|
3560
3644
|
await flushMemoryActions(client, cardId);
|