@ai-setting/roy-task-plugin 0.6.0 → 0.7.0

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 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) ?? fromEmbeddedTaskObject(text) ?? fromTaskObjectBlob(text) ?? fromSuccessLine(text, titleHint);
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 obj of topLevelObjects(text)) {
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 topLevelObjects(text) {
223
- const out = [];
224
- let depth = 0;
262
+ function jsonTree(text) {
263
+ const roots = [];
264
+ const stack = [];
225
265
  let inString = false;
226
266
  let escaped = false;
227
- let start = -1;
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 (escaped)
232
- escaped = false;
233
- else if (ch === "\\")
234
- escaped = true;
235
- else if (ch === '"')
287
+ if (ch === `
288
+ `) {
236
289
  inString = false;
237
- continue;
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
- braces++;
287
- else if (ch === "}")
288
- braces--;
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 brackets > 0 && braces <= 0;
306
+ return roots;
295
307
  }
296
308
  function fromSuccessLine(text, titleHint) {
297
309
  const m = CREATED_LINE.exec(text);
@@ -1142,12 +1154,13 @@ function createRoyAgentCardPort(options = {}) {
1142
1154
  let inFlight;
1143
1155
  const loadNotifier = async () => {
1144
1156
  const mod = await import("@ai-setting/roy-agent-core/env/task/plugins");
1145
- const hook = mod.createLarkCliTaskNotifyHook({ enabled: true, cardMode: true });
1146
- const maybeNotifier = hook.cardNotifier;
1147
- if (!maybeNotifier) {
1148
- throw new Error("roy-agent did not expose cardNotifier from createLarkCliTaskNotifyHook");
1157
+ if (typeof mod.LarkCardPatchNotifier !== "function") {
1158
+ throw new Error("roy-agent did not export LarkCardPatchNotifier from env/task/plugins");
1149
1159
  }
1150
- notifier = maybeNotifier;
1160
+ notifier = new mod.LarkCardPatchNotifier({
1161
+ pinOnStart: true,
1162
+ unpinOnFinish: true
1163
+ });
1151
1164
  return notifier;
1152
1165
  };
1153
1166
  const getNotifier = () => {
@@ -1162,6 +1175,7 @@ function createRoyAgentCardPort(options = {}) {
1162
1175
  return inFlight;
1163
1176
  };
1164
1177
  return {
1178
+ enabled: true,
1165
1179
  async start(input) {
1166
1180
  const n = await withTimeout("load", getNotifier(), opTimeoutMs);
1167
1181
  return withTimeout("start", n.startTask({
@@ -1200,6 +1214,7 @@ function createRoyAgentCardPort(options = {}) {
1200
1214
  }
1201
1215
  function createNoopCardPort() {
1202
1216
  return {
1217
+ enabled: false,
1203
1218
  async start() {
1204
1219
  return { messageId: "", pinned: false };
1205
1220
  },
@@ -1248,6 +1263,8 @@ function cardReport(handle) {
1248
1263
  out.cardMessageId = handle.messageId;
1249
1264
  if (handle.error)
1250
1265
  out.cardError = handle.error;
1266
+ if (handle.cardWantedButNoTask && !handle.messageId && !handle.error)
1267
+ out.cardExpected = true;
1251
1268
  if (handle.meta && typeof handle.meta.id === "number")
1252
1269
  out.taskId = handle.meta.id;
1253
1270
  return out;
@@ -1433,6 +1450,7 @@ class Dispatcher {
1433
1450
  plan,
1434
1451
  error: sent.error ?? "unknown",
1435
1452
  text: result.text,
1453
+ ...createdTaskReport(result.createdTask),
1436
1454
  ...cardReport(card)
1437
1455
  };
1438
1456
  }
@@ -1447,6 +1465,7 @@ class Dispatcher {
1447
1465
  plan,
1448
1466
  replyMessageId: sent.messageId,
1449
1467
  text: result.text,
1468
+ ...createdTaskReport(result.createdTask),
1450
1469
  ...cardReport(card)
1451
1470
  };
1452
1471
  };
@@ -1456,8 +1475,10 @@ class Dispatcher {
1456
1475
  const handle = { messageId: "" };
1457
1476
  if (!this.deps.card)
1458
1477
  return handle;
1459
- if (!input.createdTask)
1478
+ if (!input.createdTask) {
1479
+ handle.cardWantedButNoTask = this.deps.card.enabled === true;
1460
1480
  return handle;
1481
+ }
1461
1482
  const meta = buildCardMeta({
1462
1483
  task: input.createdTask,
1463
1484
  messageId: input.messageId,
@@ -2308,13 +2329,14 @@ function formatBanner(options, commands, maxConcurrency) {
2308
2329
  `);
2309
2330
  }
2310
2331
  function cardSuffix(result) {
2311
- if (!("cardMessageId" in result) && !("cardError" in result))
2312
- return "";
2313
- if (result.cardError)
2332
+ if ("cardError" in result && result.cardError)
2314
2333
  return ` card=FAILED(${result.cardError})`;
2315
- if (result.cardMessageId)
2334
+ if ("cardMessageId" in result && result.cardMessageId)
2316
2335
  return ` card=${result.cardMessageId}`;
2317
- return " card=none(no task created)";
2336
+ return result.cardExpected ? " card=none(no task created)" : "";
2337
+ }
2338
+ function taskSuffix(result) {
2339
+ return result.taskId === undefined ? "" : ` task=${result.taskId}`;
2318
2340
  }
2319
2341
  function formatResult(label, result) {
2320
2342
  const card = cardSuffix(result);
@@ -2326,13 +2348,13 @@ function formatResult(label, result) {
2326
2348
  case "duplicate":
2327
2349
  return `[roy-task] ${label} duplicate dropped key=${result.key ?? "(unknown)"}`;
2328
2350
  case "no-output":
2329
- return `[roy-task] ${label} no-output (agent produced no text; not replying) ` + `toolCalls=${result.toolCalls}${card}`;
2351
+ return `[roy-task] ${label} no-output (agent produced no text; not replying) ` + `toolCalls=${result.toolCalls}${taskSuffix(result)}${card}`;
2330
2352
  case "no-reply":
2331
- return `[roy-task] ${label} no-reply (reply disabled) chars=${result.text.length}${card}`;
2353
+ return `[roy-task] ${label} no-reply (reply disabled) chars=${result.text.length}${taskSuffix(result)}${card}`;
2332
2354
  case "agent-error":
2333
- return `[roy-task] ${label} agent-error: ${result.error}${card}`;
2355
+ return `[roy-task] ${label} agent-error: ${result.error}${taskSuffix(result)}${card}`;
2334
2356
  case "reply-failed":
2335
- return `[roy-task] ${label} reply-failed: ${result.error}${card}`;
2357
+ return `[roy-task] ${label} reply-failed: ${result.error}${taskSuffix(result)}${card}`;
2336
2358
  case "no-target":
2337
2359
  return `[roy-task] ${label} skipped: ${result.reason}`;
2338
2360
  }
@@ -2462,7 +2484,7 @@ function formatStatus(report) {
2462
2484
  }
2463
2485
 
2464
2486
  // ../../../packages/cli/src/main.ts
2465
- var VERSION = "0.6.0";
2487
+ var VERSION = "0.7.0";
2466
2488
  async function main(argv) {
2467
2489
  const parsed = parseArgs(argv);
2468
2490
  switch (parsed.command) {