@ai-setting/roy-task-plugin 0.6.0 → 0.6.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 +94 -73
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -142,7 +142,7 @@ var CREATED_LINE = /Task created(?:\s+successfully)?\s*:\s*#(\d+)/;
|
|
|
142
142
|
function extractCreatedTask(text, titleHint) {
|
|
143
143
|
if (!text)
|
|
144
144
|
return;
|
|
145
|
-
return fromJson(text) ??
|
|
145
|
+
return fromJson(text) ?? fromSuccessLine(text, titleHint) ?? fromEmbeddedTaskObject(text) ?? fromTaskObjectBlob(text);
|
|
146
146
|
}
|
|
147
147
|
function uniqueTaskId(text) {
|
|
148
148
|
let id;
|
|
@@ -199,10 +199,7 @@ function titleFromCreatedActionTitle(text) {
|
|
|
199
199
|
var BLOB_GATE = ['"taskId"', '"actionTitle"', "Task created:"];
|
|
200
200
|
function fromEmbeddedTaskObject(text) {
|
|
201
201
|
let found;
|
|
202
|
-
for (const
|
|
203
|
-
const task = taskFromObject(obj);
|
|
204
|
-
if (!task)
|
|
205
|
-
continue;
|
|
202
|
+
for (const task of taskCandidates(text, jsonTree(text))) {
|
|
206
203
|
if (found === undefined)
|
|
207
204
|
found = task;
|
|
208
205
|
else if (found.id !== task.id)
|
|
@@ -210,6 +207,49 @@ function fromEmbeddedTaskObject(text) {
|
|
|
210
207
|
}
|
|
211
208
|
return found;
|
|
212
209
|
}
|
|
210
|
+
function looksLikeArrayStart(text, at) {
|
|
211
|
+
for (let i = at + 1;i < text.length; i++) {
|
|
212
|
+
const ch = text[i];
|
|
213
|
+
if (ch === " " || ch === "\t" || ch === `
|
|
214
|
+
` || ch === "\r")
|
|
215
|
+
continue;
|
|
216
|
+
return ch === "{" || ch === "[" || ch === '"' || ch === "]";
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
function taskCandidates(text, roots) {
|
|
221
|
+
const out = [];
|
|
222
|
+
const pending = [...roots].reverse();
|
|
223
|
+
while (pending.length > 0) {
|
|
224
|
+
const node = pending.pop();
|
|
225
|
+
if (node.end < 0) {
|
|
226
|
+
if (node.ch === "[" && looksLikeArrayStart(text, node.start))
|
|
227
|
+
continue;
|
|
228
|
+
pushChildren(pending, node);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (node.ch === "[")
|
|
232
|
+
continue;
|
|
233
|
+
const parsed = parseObject(text, node);
|
|
234
|
+
const task = parsed ? taskFromObject(parsed) : undefined;
|
|
235
|
+
if (task)
|
|
236
|
+
out.push(task);
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
function pushChildren(pending, node) {
|
|
241
|
+
for (let i = node.children.length - 1;i >= 0; i--)
|
|
242
|
+
pending.push(node.children[i]);
|
|
243
|
+
}
|
|
244
|
+
function parseObject(text, node) {
|
|
245
|
+
try {
|
|
246
|
+
const parsed = JSON.parse(text.slice(node.start, node.end + 1));
|
|
247
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
248
|
+
return parsed;
|
|
249
|
+
}
|
|
250
|
+
} catch {}
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
213
253
|
function taskFromObject(obj) {
|
|
214
254
|
const id = obj["id"];
|
|
215
255
|
const title = obj["title"];
|
|
@@ -219,60 +259,36 @@ function taskFromObject(obj) {
|
|
|
219
259
|
return;
|
|
220
260
|
return { id, title: title.trim() };
|
|
221
261
|
}
|
|
222
|
-
function
|
|
223
|
-
const
|
|
224
|
-
|
|
262
|
+
function jsonTree(text) {
|
|
263
|
+
const roots = [];
|
|
264
|
+
const stack = [];
|
|
225
265
|
let inString = false;
|
|
226
266
|
let escaped = false;
|
|
227
|
-
|
|
267
|
+
const open = (ch, at) => {
|
|
268
|
+
const node = { ch, start: at, end: -1, children: [] };
|
|
269
|
+
const parent = stack[stack.length - 1];
|
|
270
|
+
(parent ? parent.children : roots).push(node);
|
|
271
|
+
stack.push(node);
|
|
272
|
+
};
|
|
273
|
+
const close = (ch, at) => {
|
|
274
|
+
const want = ch === "}" ? "{" : "[";
|
|
275
|
+
let k = stack.length - 1;
|
|
276
|
+
while (k >= 0 && stack[k].ch !== want)
|
|
277
|
+
k--;
|
|
278
|
+
if (k < 0)
|
|
279
|
+
return;
|
|
280
|
+
stack.length = k + 1;
|
|
281
|
+
const node = stack.pop();
|
|
282
|
+
node.end = at;
|
|
283
|
+
};
|
|
228
284
|
for (let i = 0;i < text.length; i++) {
|
|
229
285
|
const ch = text[i];
|
|
230
286
|
if (inString) {
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
else if (ch === "\\")
|
|
234
|
-
escaped = true;
|
|
235
|
-
else if (ch === '"')
|
|
287
|
+
if (ch === `
|
|
288
|
+
`) {
|
|
236
289
|
inString = false;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (ch === '"') {
|
|
240
|
-
inString = true;
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
if (ch === "{") {
|
|
244
|
-
if (depth === 0 && !insideArray(text, i))
|
|
245
|
-
start = i;
|
|
246
|
-
depth++;
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
if (ch === "]" && depth === 0)
|
|
250
|
-
continue;
|
|
251
|
-
if (ch !== "}")
|
|
252
|
-
continue;
|
|
253
|
-
depth--;
|
|
254
|
-
if (depth !== 0 || start < 0)
|
|
255
|
-
continue;
|
|
256
|
-
const slice = text.slice(start, i + 1);
|
|
257
|
-
start = -1;
|
|
258
|
-
try {
|
|
259
|
-
const parsed = JSON.parse(slice);
|
|
260
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
261
|
-
out.push(parsed);
|
|
262
|
-
}
|
|
263
|
-
} catch {}
|
|
264
|
-
}
|
|
265
|
-
return out;
|
|
266
|
-
}
|
|
267
|
-
function insideArray(text, at) {
|
|
268
|
-
let brackets = 0;
|
|
269
|
-
let braces = 0;
|
|
270
|
-
let inString = false;
|
|
271
|
-
let escaped = false;
|
|
272
|
-
for (let i = 0;i < at; i++) {
|
|
273
|
-
const ch = text[i];
|
|
274
|
-
if (inString) {
|
|
275
|
-
if (escaped)
|
|
290
|
+
escaped = false;
|
|
291
|
+
} else if (escaped)
|
|
276
292
|
escaped = false;
|
|
277
293
|
else if (ch === "\\")
|
|
278
294
|
escaped = true;
|
|
@@ -282,16 +298,12 @@ function insideArray(text, at) {
|
|
|
282
298
|
}
|
|
283
299
|
if (ch === '"')
|
|
284
300
|
inString = true;
|
|
285
|
-
else if (ch === "{")
|
|
286
|
-
|
|
287
|
-
else if (ch === "}")
|
|
288
|
-
|
|
289
|
-
else if (ch === "[")
|
|
290
|
-
brackets++;
|
|
291
|
-
else if (ch === "]")
|
|
292
|
-
brackets--;
|
|
301
|
+
else if (ch === "{" || ch === "[")
|
|
302
|
+
open(ch, i);
|
|
303
|
+
else if (ch === "}" || ch === "]")
|
|
304
|
+
close(ch, i);
|
|
293
305
|
}
|
|
294
|
-
return
|
|
306
|
+
return roots;
|
|
295
307
|
}
|
|
296
308
|
function fromSuccessLine(text, titleHint) {
|
|
297
309
|
const m = CREATED_LINE.exec(text);
|
|
@@ -1162,6 +1174,7 @@ function createRoyAgentCardPort(options = {}) {
|
|
|
1162
1174
|
return inFlight;
|
|
1163
1175
|
};
|
|
1164
1176
|
return {
|
|
1177
|
+
enabled: true,
|
|
1165
1178
|
async start(input) {
|
|
1166
1179
|
const n = await withTimeout("load", getNotifier(), opTimeoutMs);
|
|
1167
1180
|
return withTimeout("start", n.startTask({
|
|
@@ -1200,6 +1213,7 @@ function createRoyAgentCardPort(options = {}) {
|
|
|
1200
1213
|
}
|
|
1201
1214
|
function createNoopCardPort() {
|
|
1202
1215
|
return {
|
|
1216
|
+
enabled: false,
|
|
1203
1217
|
async start() {
|
|
1204
1218
|
return { messageId: "", pinned: false };
|
|
1205
1219
|
},
|
|
@@ -1248,6 +1262,8 @@ function cardReport(handle) {
|
|
|
1248
1262
|
out.cardMessageId = handle.messageId;
|
|
1249
1263
|
if (handle.error)
|
|
1250
1264
|
out.cardError = handle.error;
|
|
1265
|
+
if (handle.cardWantedButNoTask && !handle.messageId && !handle.error)
|
|
1266
|
+
out.cardExpected = true;
|
|
1251
1267
|
if (handle.meta && typeof handle.meta.id === "number")
|
|
1252
1268
|
out.taskId = handle.meta.id;
|
|
1253
1269
|
return out;
|
|
@@ -1433,6 +1449,7 @@ class Dispatcher {
|
|
|
1433
1449
|
plan,
|
|
1434
1450
|
error: sent.error ?? "unknown",
|
|
1435
1451
|
text: result.text,
|
|
1452
|
+
...createdTaskReport(result.createdTask),
|
|
1436
1453
|
...cardReport(card)
|
|
1437
1454
|
};
|
|
1438
1455
|
}
|
|
@@ -1447,6 +1464,7 @@ class Dispatcher {
|
|
|
1447
1464
|
plan,
|
|
1448
1465
|
replyMessageId: sent.messageId,
|
|
1449
1466
|
text: result.text,
|
|
1467
|
+
...createdTaskReport(result.createdTask),
|
|
1450
1468
|
...cardReport(card)
|
|
1451
1469
|
};
|
|
1452
1470
|
};
|
|
@@ -1456,8 +1474,10 @@ class Dispatcher {
|
|
|
1456
1474
|
const handle = { messageId: "" };
|
|
1457
1475
|
if (!this.deps.card)
|
|
1458
1476
|
return handle;
|
|
1459
|
-
if (!input.createdTask)
|
|
1477
|
+
if (!input.createdTask) {
|
|
1478
|
+
handle.cardWantedButNoTask = this.deps.card.enabled === true;
|
|
1460
1479
|
return handle;
|
|
1480
|
+
}
|
|
1461
1481
|
const meta = buildCardMeta({
|
|
1462
1482
|
task: input.createdTask,
|
|
1463
1483
|
messageId: input.messageId,
|
|
@@ -2308,13 +2328,14 @@ function formatBanner(options, commands, maxConcurrency) {
|
|
|
2308
2328
|
`);
|
|
2309
2329
|
}
|
|
2310
2330
|
function cardSuffix(result) {
|
|
2311
|
-
if (
|
|
2312
|
-
return "";
|
|
2313
|
-
if (result.cardError)
|
|
2331
|
+
if ("cardError" in result && result.cardError)
|
|
2314
2332
|
return ` card=FAILED(${result.cardError})`;
|
|
2315
|
-
if (result.cardMessageId)
|
|
2333
|
+
if ("cardMessageId" in result && result.cardMessageId)
|
|
2316
2334
|
return ` card=${result.cardMessageId}`;
|
|
2317
|
-
return " card=none(no task created)";
|
|
2335
|
+
return result.cardExpected ? " card=none(no task created)" : "";
|
|
2336
|
+
}
|
|
2337
|
+
function taskSuffix(result) {
|
|
2338
|
+
return result.taskId === undefined ? "" : ` task=${result.taskId}`;
|
|
2318
2339
|
}
|
|
2319
2340
|
function formatResult(label, result) {
|
|
2320
2341
|
const card = cardSuffix(result);
|
|
@@ -2326,13 +2347,13 @@ function formatResult(label, result) {
|
|
|
2326
2347
|
case "duplicate":
|
|
2327
2348
|
return `[roy-task] ${label} duplicate dropped key=${result.key ?? "(unknown)"}`;
|
|
2328
2349
|
case "no-output":
|
|
2329
|
-
return `[roy-task] ${label} no-output (agent produced no text; not replying) ` + `toolCalls=${result.toolCalls}${card}`;
|
|
2350
|
+
return `[roy-task] ${label} no-output (agent produced no text; not replying) ` + `toolCalls=${result.toolCalls}${taskSuffix(result)}${card}`;
|
|
2330
2351
|
case "no-reply":
|
|
2331
|
-
return `[roy-task] ${label} no-reply (reply disabled) chars=${result.text.length}${card}`;
|
|
2352
|
+
return `[roy-task] ${label} no-reply (reply disabled) chars=${result.text.length}${taskSuffix(result)}${card}`;
|
|
2332
2353
|
case "agent-error":
|
|
2333
|
-
return `[roy-task] ${label} agent-error: ${result.error}${card}`;
|
|
2354
|
+
return `[roy-task] ${label} agent-error: ${result.error}${taskSuffix(result)}${card}`;
|
|
2334
2355
|
case "reply-failed":
|
|
2335
|
-
return `[roy-task] ${label} reply-failed: ${result.error}${card}`;
|
|
2356
|
+
return `[roy-task] ${label} reply-failed: ${result.error}${taskSuffix(result)}${card}`;
|
|
2336
2357
|
case "no-target":
|
|
2337
2358
|
return `[roy-task] ${label} skipped: ${result.reason}`;
|
|
2338
2359
|
}
|
|
@@ -2462,7 +2483,7 @@ function formatStatus(report) {
|
|
|
2462
2483
|
}
|
|
2463
2484
|
|
|
2464
2485
|
// ../../../packages/cli/src/main.ts
|
|
2465
|
-
var VERSION = "0.6.
|
|
2486
|
+
var VERSION = "0.6.1";
|
|
2466
2487
|
async function main(argv) {
|
|
2467
2488
|
const parsed = parseArgs(argv);
|
|
2468
2489
|
switch (parsed.command) {
|