@ai-setting/roy-agent-core 1.5.58 → 1.5.60
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/env/agent/index.js +2 -2
- package/dist/env/event-source/index.js +2 -2
- package/dist/env/index.js +9 -9
- package/dist/env/llm/index.js +2 -2
- package/dist/env/prompt/index.js +1 -1
- package/dist/env/task/delegate/index.js +1 -1
- package/dist/env/task/index.js +4 -4
- package/dist/env/task/plugins/index.js +1 -1
- package/dist/env/task/storage/index.js +1 -1
- package/dist/env/task/tools/index.js +8 -2
- package/dist/index.js +11 -11
- package/dist/shared/@ai-setting/{roy-agent-core-e1704378.js → roy-agent-core-3s9va046.js} +198 -8
- package/dist/shared/@ai-setting/{roy-agent-core-q16bh5e9.js → roy-agent-core-8am1xdvb.js} +21 -7
- package/dist/shared/@ai-setting/{roy-agent-core-w4f871e2.js → roy-agent-core-cgq7btak.js} +233 -34
- package/dist/shared/@ai-setting/{roy-agent-core-0hhxwz5f.js → roy-agent-core-dkevkmas.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-6ph5va4n.js → roy-agent-core-hg3q4f82.js} +19 -9
- package/dist/shared/@ai-setting/{roy-agent-core-65yjzwv5.js → roy-agent-core-nd3amf4x.js} +5 -2
- package/dist/shared/@ai-setting/{roy-agent-core-6s3vec2y.js → roy-agent-core-qqhbxq56.js} +72 -5
- package/dist/shared/@ai-setting/{roy-agent-core-zkwe508t.js → roy-agent-core-s2zz85a9.js} +19 -2
- package/dist/shared/@ai-setting/{roy-agent-core-5c2mfq1q.js → roy-agent-core-t3367jkk.js} +2 -0
- package/dist/shared/@ai-setting/{roy-agent-core-skaha0yj.js → roy-agent-core-wqzkxab9.js} +32 -5
- package/dist/shared/@ai-setting/{roy-agent-core-sfqx98j6.js → roy-agent-core-xztzw1yb.js} +1 -1
- package/package.json +1 -1
|
@@ -184,6 +184,7 @@ class SQLiteTaskStore {
|
|
|
184
184
|
)
|
|
185
185
|
`);
|
|
186
186
|
this.db.run("CREATE INDEX IF NOT EXISTS idx_task_tag_relation_tag_id ON task_tag_relation(tag_id)");
|
|
187
|
+
this.db.run("CREATE INDEX IF NOT EXISTS idx_task_parent_task_id ON task(parent_task_id)");
|
|
187
188
|
if (this.dbPath !== ":memory:") {
|
|
188
189
|
try {
|
|
189
190
|
const { runMigration: runMigration001 } = (init_001_add_project_path_context(), __toCommonJS(exports_001_add_project_path_context));
|
|
@@ -308,24 +309,36 @@ class SQLiteTaskStore {
|
|
|
308
309
|
}
|
|
309
310
|
async listTasks(options) {
|
|
310
311
|
await this.initialize();
|
|
311
|
-
|
|
312
|
-
|
|
312
|
+
if (options?.depth !== undefined && options.depth >= 0 && options.parent_task_id === undefined) {
|
|
313
|
+
return this.listTasksByDepth(options);
|
|
314
|
+
}
|
|
315
|
+
const whereClauses = ["1=1"];
|
|
316
|
+
const whereParams = [];
|
|
313
317
|
if (options?.status) {
|
|
314
|
-
|
|
315
|
-
|
|
318
|
+
whereClauses.push("status = ?");
|
|
319
|
+
whereParams.push(options.status);
|
|
316
320
|
}
|
|
317
321
|
if (options?.priority) {
|
|
318
|
-
|
|
319
|
-
|
|
322
|
+
whereClauses.push("priority = ?");
|
|
323
|
+
whereParams.push(options.priority);
|
|
320
324
|
}
|
|
321
325
|
if (options?.type) {
|
|
322
|
-
|
|
323
|
-
|
|
326
|
+
whereClauses.push("type = ?");
|
|
327
|
+
whereParams.push(options.type);
|
|
324
328
|
}
|
|
325
329
|
if (options?.parent_task_id !== undefined) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
330
|
+
whereClauses.push("parent_task_id = ?");
|
|
331
|
+
whereParams.push(options.parent_task_id);
|
|
332
|
+
}
|
|
333
|
+
if (!options?.include_archived && options?.status !== "archived") {
|
|
334
|
+
whereClauses.push("status != 'archived'");
|
|
335
|
+
}
|
|
336
|
+
const whereSql = whereClauses.join(" AND ");
|
|
337
|
+
const countSql = `SELECT COUNT(*) as total FROM task WHERE ${whereSql}`;
|
|
338
|
+
const countRow = this.db.prepare(countSql).get(...whereParams);
|
|
339
|
+
const total = countRow?.total ?? 0;
|
|
340
|
+
let sql = `SELECT * FROM task WHERE ${whereSql}`;
|
|
341
|
+
const params = [...whereParams];
|
|
329
342
|
sql += " ORDER BY updated_at DESC";
|
|
330
343
|
if (options?.limit) {
|
|
331
344
|
sql += " LIMIT ?";
|
|
@@ -337,11 +350,96 @@ class SQLiteTaskStore {
|
|
|
337
350
|
}
|
|
338
351
|
const stmt = this.db.prepare(sql);
|
|
339
352
|
const rows = stmt.all(...params);
|
|
340
|
-
|
|
353
|
+
const tasks = rows.map((row) => {
|
|
341
354
|
const task = this.rowToTask(row);
|
|
342
355
|
this.tasksCache.set(task.id, task);
|
|
343
356
|
return task;
|
|
344
357
|
});
|
|
358
|
+
return { tasks, total };
|
|
359
|
+
}
|
|
360
|
+
async listTasksByDepth(options) {
|
|
361
|
+
const depth = options.depth ?? 0;
|
|
362
|
+
const filterClauses = ["1=1"];
|
|
363
|
+
const filterParams = [];
|
|
364
|
+
if (options.status) {
|
|
365
|
+
filterClauses.push("status = ?");
|
|
366
|
+
filterParams.push(options.status);
|
|
367
|
+
}
|
|
368
|
+
if (options.priority) {
|
|
369
|
+
filterClauses.push("priority = ?");
|
|
370
|
+
filterParams.push(options.priority);
|
|
371
|
+
}
|
|
372
|
+
if (options.type) {
|
|
373
|
+
filterClauses.push("type = ?");
|
|
374
|
+
filterParams.push(options.type);
|
|
375
|
+
}
|
|
376
|
+
if (!options?.include_archived && options?.status !== "archived") {
|
|
377
|
+
filterClauses.push("status != 'archived'");
|
|
378
|
+
}
|
|
379
|
+
const filterSql = filterClauses.join(" AND ");
|
|
380
|
+
const collected = [];
|
|
381
|
+
if (depth === 0) {
|
|
382
|
+
const rootSql = `SELECT * FROM task WHERE parent_task_id IS NULL AND ${filterSql} ORDER BY updated_at DESC`;
|
|
383
|
+
const rows = this.db.prepare(rootSql).all(...filterParams);
|
|
384
|
+
for (const row of rows) {
|
|
385
|
+
const t = this.rowToTask(row);
|
|
386
|
+
this.tasksCache.set(t.id, t);
|
|
387
|
+
collected.push(t);
|
|
388
|
+
}
|
|
389
|
+
} else {
|
|
390
|
+
const rootRows = this.db.prepare(`SELECT * FROM task WHERE parent_task_id IS NULL AND ${filterSql} ORDER BY updated_at DESC`).all(...filterParams);
|
|
391
|
+
let currentLevel = rootRows.map((row) => {
|
|
392
|
+
const t = this.rowToTask(row);
|
|
393
|
+
this.tasksCache.set(t.id, t);
|
|
394
|
+
return t;
|
|
395
|
+
});
|
|
396
|
+
collected.push(...currentLevel);
|
|
397
|
+
for (let level = 1;level <= depth; level++) {
|
|
398
|
+
if (currentLevel.length === 0)
|
|
399
|
+
break;
|
|
400
|
+
const ids = currentLevel.map((t) => t.id);
|
|
401
|
+
const placeholders = ids.map(() => "?").join(",");
|
|
402
|
+
const childSql = `SELECT * FROM task WHERE parent_task_id IN (${placeholders}) AND ${filterSql} ORDER BY updated_at DESC`;
|
|
403
|
+
const childRows = this.db.prepare(childSql).all(...ids, ...filterParams);
|
|
404
|
+
const nextLevel = childRows.map((row) => {
|
|
405
|
+
const t = this.rowToTask(row);
|
|
406
|
+
this.tasksCache.set(t.id, t);
|
|
407
|
+
return t;
|
|
408
|
+
});
|
|
409
|
+
collected.push(...nextLevel);
|
|
410
|
+
currentLevel = nextLevel;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const total = collected.length;
|
|
414
|
+
const offset = options.offset ?? 0;
|
|
415
|
+
const limit = options.limit ?? total;
|
|
416
|
+
const sliced = collected.slice(offset, offset + limit);
|
|
417
|
+
return { tasks: sliced, total };
|
|
418
|
+
}
|
|
419
|
+
async getTaskTree(taskId, depth = -1) {
|
|
420
|
+
await this.initialize();
|
|
421
|
+
const result = [];
|
|
422
|
+
let currentLevel = [taskId];
|
|
423
|
+
let currentDepth = 0;
|
|
424
|
+
while (currentLevel.length > 0) {
|
|
425
|
+
if (depth !== -1 && currentDepth >= depth)
|
|
426
|
+
break;
|
|
427
|
+
const placeholders = currentLevel.map(() => "?").join(",");
|
|
428
|
+
const rows = this.db.prepare(`SELECT * FROM task WHERE parent_task_id IN (${placeholders}) ORDER BY updated_at DESC`).all(...currentLevel);
|
|
429
|
+
const nextLevel = [];
|
|
430
|
+
for (const row of rows) {
|
|
431
|
+
const t = this.rowToTask(row);
|
|
432
|
+
this.tasksCache.set(t.id, t);
|
|
433
|
+
result.push(t);
|
|
434
|
+
nextLevel.push(t.id);
|
|
435
|
+
}
|
|
436
|
+
currentLevel = nextLevel;
|
|
437
|
+
currentDepth++;
|
|
438
|
+
}
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
async getChildTasks(taskId, options = {}) {
|
|
442
|
+
return this.listTasks({ ...options, parent_task_id: taskId });
|
|
345
443
|
}
|
|
346
444
|
async createOperation(options) {
|
|
347
445
|
await this.initialize();
|
|
@@ -599,9 +697,13 @@ class SQLiteTaskStore {
|
|
|
599
697
|
async searchTasksByKeywords(keywords, options = {}) {
|
|
600
698
|
await this.initialize();
|
|
601
699
|
if (!keywords || keywords.length === 0) {
|
|
602
|
-
return [];
|
|
700
|
+
return { tasks: [], total: 0 };
|
|
701
|
+
}
|
|
702
|
+
const { limit = 20, offset = 0, excludeTaskId, status, priority, type, depth } = options;
|
|
703
|
+
let allowedTaskIds = null;
|
|
704
|
+
if (depth !== undefined && depth >= 0) {
|
|
705
|
+
allowedTaskIds = await this.collectTaskIdsByDepth(depth);
|
|
603
706
|
}
|
|
604
|
-
const { limit = 20, excludeTaskId } = options;
|
|
605
707
|
const tasks = new Map;
|
|
606
708
|
let taskSql = "SELECT * FROM task WHERE 1=1";
|
|
607
709
|
const taskParams = [];
|
|
@@ -609,17 +711,37 @@ class SQLiteTaskStore {
|
|
|
609
711
|
taskSql += " AND id != ?";
|
|
610
712
|
taskParams.push(excludeTaskId);
|
|
611
713
|
}
|
|
714
|
+
if (status) {
|
|
715
|
+
taskSql += " AND status = ?";
|
|
716
|
+
taskParams.push(status);
|
|
717
|
+
}
|
|
718
|
+
if (priority) {
|
|
719
|
+
taskSql += " AND priority = ?";
|
|
720
|
+
taskParams.push(priority);
|
|
721
|
+
}
|
|
722
|
+
if (type) {
|
|
723
|
+
taskSql += " AND type = ?";
|
|
724
|
+
taskParams.push(type);
|
|
725
|
+
}
|
|
726
|
+
if (!options?.include_archived && options?.status !== "archived") {
|
|
727
|
+
taskSql += " AND status != 'archived'";
|
|
728
|
+
}
|
|
729
|
+
const scanLimit = Math.max(limit * 5, 200);
|
|
612
730
|
taskSql += " ORDER BY updated_at DESC LIMIT ?";
|
|
613
|
-
taskParams.push(
|
|
731
|
+
taskParams.push(scanLimit);
|
|
614
732
|
const taskRows = this.db.prepare(taskSql).all(...taskParams);
|
|
615
733
|
for (const row of taskRows) {
|
|
616
734
|
const task = this.rowToTask(row);
|
|
735
|
+
const matchedKeywords = new Set;
|
|
617
736
|
let matchCount = 0;
|
|
618
737
|
if (task.title) {
|
|
619
738
|
const lowerTitle = task.title.toLowerCase();
|
|
620
739
|
for (const keyword of keywords) {
|
|
621
740
|
if (lowerTitle.includes(keyword.toLowerCase())) {
|
|
622
|
-
|
|
741
|
+
{
|
|
742
|
+
matchCount++;
|
|
743
|
+
matchedKeywords.add(keyword);
|
|
744
|
+
}
|
|
623
745
|
}
|
|
624
746
|
}
|
|
625
747
|
}
|
|
@@ -627,7 +749,10 @@ class SQLiteTaskStore {
|
|
|
627
749
|
for (const keyword of keywords) {
|
|
628
750
|
const lowerKeyword = keyword.toLowerCase();
|
|
629
751
|
if (task.tags.some((tag) => tag.toLowerCase().includes(lowerKeyword))) {
|
|
630
|
-
|
|
752
|
+
{
|
|
753
|
+
matchCount += 2;
|
|
754
|
+
matchedKeywords.add(keyword);
|
|
755
|
+
}
|
|
631
756
|
}
|
|
632
757
|
}
|
|
633
758
|
}
|
|
@@ -635,7 +760,10 @@ class SQLiteTaskStore {
|
|
|
635
760
|
const lowerDesc = task.description.toLowerCase();
|
|
636
761
|
for (const keyword of keywords) {
|
|
637
762
|
if (lowerDesc.includes(keyword.toLowerCase())) {
|
|
638
|
-
|
|
763
|
+
{
|
|
764
|
+
matchCount++;
|
|
765
|
+
matchedKeywords.add(keyword);
|
|
766
|
+
}
|
|
639
767
|
}
|
|
640
768
|
}
|
|
641
769
|
}
|
|
@@ -643,11 +771,14 @@ class SQLiteTaskStore {
|
|
|
643
771
|
const lowerGoals = task.goals_and_expected_deliverables.toLowerCase();
|
|
644
772
|
for (const keyword of keywords) {
|
|
645
773
|
if (lowerGoals.includes(keyword.toLowerCase())) {
|
|
646
|
-
|
|
774
|
+
{
|
|
775
|
+
matchCount++;
|
|
776
|
+
matchedKeywords.add(keyword);
|
|
777
|
+
}
|
|
647
778
|
}
|
|
648
779
|
}
|
|
649
780
|
}
|
|
650
|
-
if (
|
|
781
|
+
if (matchedKeywords.size === keywords.length) {
|
|
651
782
|
tasks.set(task.id, { task, matchCount });
|
|
652
783
|
}
|
|
653
784
|
}
|
|
@@ -659,31 +790,99 @@ class SQLiteTaskStore {
|
|
|
659
790
|
AND (action_title LIKE ? OR action_description LIKE ?)
|
|
660
791
|
LIMIT 10
|
|
661
792
|
`;
|
|
793
|
+
const opMatchedKeywords = new Set;
|
|
662
794
|
for (const keyword of keywords) {
|
|
663
795
|
const pattern = `%${keyword}%`;
|
|
664
796
|
const ops = this.db.prepare(opSql).all(opRow.task_id, pattern, pattern);
|
|
665
797
|
if (ops.length > 0) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
798
|
+
opMatchedKeywords.add(keyword);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (opMatchedKeywords.size === 0)
|
|
802
|
+
continue;
|
|
803
|
+
const taskRow = this.db.prepare("SELECT * FROM task WHERE id = ?").get(opRow.task_id);
|
|
804
|
+
if (!taskRow)
|
|
805
|
+
continue;
|
|
806
|
+
const task = this.rowToTask(taskRow);
|
|
807
|
+
if (excludeTaskId && task.id === excludeTaskId)
|
|
808
|
+
continue;
|
|
809
|
+
if (status && task.status !== status)
|
|
810
|
+
continue;
|
|
811
|
+
if (priority && task.priority !== priority)
|
|
812
|
+
continue;
|
|
813
|
+
if (type && task.type !== type)
|
|
814
|
+
continue;
|
|
815
|
+
if (!options?.include_archived && task.status === "archived")
|
|
816
|
+
continue;
|
|
817
|
+
const existing = tasks.get(task.id);
|
|
818
|
+
if (existing) {
|
|
819
|
+
existing.matchCount += 2;
|
|
820
|
+
} else {
|
|
821
|
+
const combinedKeywords = new Set(opMatchedKeywords);
|
|
822
|
+
if (task.title) {
|
|
823
|
+
const lowerTitle = task.title.toLowerCase();
|
|
824
|
+
for (const kw of keywords) {
|
|
825
|
+
if (lowerTitle.includes(kw.toLowerCase()))
|
|
826
|
+
combinedKeywords.add(kw);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
if (task.description) {
|
|
830
|
+
const lowerDesc = task.description.toLowerCase();
|
|
831
|
+
for (const kw of keywords) {
|
|
832
|
+
if (lowerDesc.includes(kw.toLowerCase()))
|
|
833
|
+
combinedKeywords.add(kw);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
if (task.goals_and_expected_deliverables) {
|
|
837
|
+
const lowerGoals = task.goals_and_expected_deliverables.toLowerCase();
|
|
838
|
+
for (const kw of keywords) {
|
|
839
|
+
if (lowerGoals.includes(kw.toLowerCase()))
|
|
840
|
+
combinedKeywords.add(kw);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (task.tags && Array.isArray(task.tags)) {
|
|
844
|
+
for (const kw of keywords) {
|
|
845
|
+
if (task.tags.some((tag) => tag.toLowerCase().includes(kw.toLowerCase())))
|
|
846
|
+
combinedKeywords.add(kw);
|
|
677
847
|
}
|
|
678
848
|
}
|
|
849
|
+
if (combinedKeywords.size === keywords.length) {
|
|
850
|
+
tasks.set(task.id, { task, matchCount: 2 });
|
|
851
|
+
}
|
|
679
852
|
}
|
|
680
853
|
}
|
|
681
|
-
|
|
682
|
-
|
|
854
|
+
let sorted = Array.from(tasks.values()).sort((a, b) => b.matchCount - a.matchCount);
|
|
855
|
+
if (allowedTaskIds !== null) {
|
|
856
|
+
sorted = sorted.filter((item) => allowedTaskIds.has(item.task.id));
|
|
857
|
+
}
|
|
858
|
+
const total = sorted.length;
|
|
859
|
+
const sliced = sorted.slice(offset, offset + limit);
|
|
860
|
+
const resultTasks = sliced.map((item) => item.task);
|
|
861
|
+
return { tasks: resultTasks, total };
|
|
862
|
+
}
|
|
863
|
+
async collectTaskIdsByDepth(depth) {
|
|
864
|
+
const ids = new Set;
|
|
865
|
+
const rootRows = this.db.prepare("SELECT id FROM task WHERE parent_task_id IS NULL").all();
|
|
866
|
+
let currentLevel = rootRows.map((r) => r.id);
|
|
867
|
+
for (const id of currentLevel)
|
|
868
|
+
ids.add(id);
|
|
869
|
+
if (depth === 0)
|
|
870
|
+
return ids;
|
|
871
|
+
for (let level = 1;level <= depth; level++) {
|
|
872
|
+
if (currentLevel.length === 0)
|
|
873
|
+
break;
|
|
874
|
+
const placeholders = currentLevel.map(() => "?").join(",");
|
|
875
|
+
const rows = this.db.prepare(`SELECT id FROM task WHERE parent_task_id IN (${placeholders})`).all(...currentLevel);
|
|
876
|
+
currentLevel = rows.map((r) => r.id);
|
|
877
|
+
for (const id of currentLevel)
|
|
878
|
+
ids.add(id);
|
|
879
|
+
}
|
|
880
|
+
return ids;
|
|
683
881
|
}
|
|
684
882
|
async findSimilarTasksByKeywords(keywords, options = {}) {
|
|
685
883
|
const mergedOptions = { ...options, limit: options.limit ?? 5 };
|
|
686
|
-
|
|
884
|
+
const result = await this.searchTasksByKeywords(keywords, mergedOptions);
|
|
885
|
+
return result.tasks;
|
|
687
886
|
}
|
|
688
887
|
async findSimilarTasks(taskId, limit = 5) {
|
|
689
888
|
await this.initialize();
|
|
@@ -642,7 +642,7 @@ No need to poll — just wait for the notification and use \`task_get\` with the
|
|
|
642
642
|
phase: "before",
|
|
643
643
|
hookPoint: TaskHookPoints.DELEGATE_BEFORE
|
|
644
644
|
};
|
|
645
|
-
await globalHookManager.execute(TaskHookPoints.DELEGATE_BEFORE,
|
|
645
|
+
await globalHookManager.execute(TaskHookPoints.DELEGATE_BEFORE, delegateCtx, { sessionId: parentSessionId });
|
|
646
646
|
promptWithTaskInfo = delegateCtx.prompt;
|
|
647
647
|
return await handleBackgroundTask(backgroundTaskManager, parentSessionId, description, promptWithTaskInfo, delegateCtx.subagentType, delegateCtx.timeout);
|
|
648
648
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
withTimeout
|
|
3
|
-
} from "./roy-agent-core-
|
|
3
|
+
} from "./roy-agent-core-nd3amf4x.js";
|
|
4
4
|
import {
|
|
5
5
|
AskUserError,
|
|
6
6
|
init_workflow_hil
|
|
@@ -575,14 +575,14 @@ class AgentComponent extends BaseComponent {
|
|
|
575
575
|
agentContext: parentEnvContext?.agentContext ?? {},
|
|
576
576
|
traceId: effectiveContext.metadata?.traceId,
|
|
577
577
|
sessionId: effectiveContext.sessionId,
|
|
578
|
-
userId: effectiveContext.metadata?.userId ?? "",
|
|
578
|
+
userId: parentEnvContext?.userId ?? (effectiveContext.metadata?.userId ?? ""),
|
|
579
579
|
messageId: effectiveContext.metadata?.messageId,
|
|
580
|
-
pluginEnabled: effectiveContext.pluginEnabled,
|
|
580
|
+
pluginEnabled: { ...parentEnvContext?.pluginEnabled ?? {}, ...effectiveContext.pluginEnabled ?? {} },
|
|
581
581
|
plugins: effectiveContext.plugins,
|
|
582
|
-
envEvent: effectiveContext.envEvent,
|
|
583
|
-
replyChannel: effectiveContext.envEvent?.metadata?.replyChannel,
|
|
584
|
-
sourceId: effectiveContext.envEvent?.metadata?.sourceId,
|
|
585
|
-
sourceType: effectiveContext.envEvent?.metadata?.sourceType,
|
|
582
|
+
envEvent: effectiveContext.envEvent ?? parentEnvContext?.envEvent,
|
|
583
|
+
replyChannel: parentEnvContext?.replyChannel ?? effectiveContext.envEvent?.metadata?.replyChannel,
|
|
584
|
+
sourceId: parentEnvContext?.sourceId ?? effectiveContext.envEvent?.metadata?.sourceId,
|
|
585
|
+
sourceType: parentEnvContext?.sourceType ?? effectiveContext.envEvent?.metadata?.sourceType,
|
|
586
586
|
metadata: { ...effectiveContext.metadata }
|
|
587
587
|
};
|
|
588
588
|
return await runWithEnvContextAsync(envContext, async () => {
|
|
@@ -647,9 +647,19 @@ class AgentComponent extends BaseComponent {
|
|
|
647
647
|
break;
|
|
648
648
|
}
|
|
649
649
|
finalText = llmOutput.content;
|
|
650
|
+
const assistantParts = [
|
|
651
|
+
{ type: "text", text: llmOutput.content }
|
|
652
|
+
];
|
|
653
|
+
if (llmOutput.reasoning) {
|
|
654
|
+
assistantParts.push({
|
|
655
|
+
type: "reasoning",
|
|
656
|
+
text: llmOutput.reasoning,
|
|
657
|
+
reasoningType: "core"
|
|
658
|
+
});
|
|
659
|
+
}
|
|
650
660
|
this.pushMessage(hookCtx, {
|
|
651
661
|
role: "assistant",
|
|
652
|
-
content:
|
|
662
|
+
content: assistantParts
|
|
653
663
|
});
|
|
654
664
|
break;
|
|
655
665
|
}
|
|
@@ -1030,7 +1040,7 @@ ${additionInfo}`
|
|
|
1030
1040
|
},
|
|
1031
1041
|
abortSignal: ctx.context.abort
|
|
1032
1042
|
});
|
|
1033
|
-
const result = await withTimeout(llmPromise,
|
|
1043
|
+
const result = await withTimeout(llmPromise, 300000, "LLM invocation timeout after 300s");
|
|
1034
1044
|
logger.debug("[invokeLLM] LLMComponent.invoke returned successfully");
|
|
1035
1045
|
return {
|
|
1036
1046
|
content: result.output?.content || "",
|
|
@@ -384,6 +384,7 @@ async function invoke(config, options, ctx) {
|
|
|
384
384
|
};
|
|
385
385
|
const result = await streamText(streamTextOptions);
|
|
386
386
|
let fullContent = "";
|
|
387
|
+
let rawFullContent = "";
|
|
387
388
|
let reasoningContent = "";
|
|
388
389
|
const toolCalls = [];
|
|
389
390
|
let usageInfo;
|
|
@@ -405,6 +406,7 @@ async function invoke(config, options, ctx) {
|
|
|
405
406
|
isThinkingTagOpen = thinkingResult.isThinkingTagOpen;
|
|
406
407
|
currentThinkingContent = thinkingResult.currentThinkingContent;
|
|
407
408
|
fullContent += thinkingResult.cleanedText;
|
|
409
|
+
rawFullContent += textDelta;
|
|
408
410
|
for (const reasoningSnapshot of thinkingResult.reasoningEvents) {
|
|
409
411
|
const delta = reasoningSnapshot.slice(reasoningContent.length);
|
|
410
412
|
reasoningContent = reasoningSnapshot;
|
|
@@ -417,6 +419,7 @@ async function invoke(config, options, ctx) {
|
|
|
417
419
|
}
|
|
418
420
|
} else {
|
|
419
421
|
fullContent += textDelta;
|
|
422
|
+
rawFullContent += textDelta;
|
|
420
423
|
if (emitToEnv) {
|
|
421
424
|
emitToEnv({ type: "text", content: fullContent, delta: textDelta });
|
|
422
425
|
}
|
|
@@ -477,7 +480,7 @@ async function invoke(config, options, ctx) {
|
|
|
477
480
|
return {
|
|
478
481
|
toolCallId: firstToolCall.id,
|
|
479
482
|
result: JSON.stringify({
|
|
480
|
-
content:
|
|
483
|
+
content: rawFullContent,
|
|
481
484
|
reasoning: reasoningContent || undefined,
|
|
482
485
|
tool_calls: toolCalls.map((tc) => ({
|
|
483
486
|
id: tc.id,
|
|
@@ -492,7 +495,7 @@ async function invoke(config, options, ctx) {
|
|
|
492
495
|
return {
|
|
493
496
|
toolCallId: "invoke-" + Date.now(),
|
|
494
497
|
result: JSON.stringify({
|
|
495
|
-
content:
|
|
498
|
+
content: rawFullContent,
|
|
496
499
|
reasoning: reasoningContent || undefined,
|
|
497
500
|
usage: usageInfo,
|
|
498
501
|
model
|
|
@@ -402,6 +402,7 @@ var NotifyType;
|
|
|
402
402
|
NotifyType2["TASK_COMPLETED"] = "task_completed";
|
|
403
403
|
NotifyType2["TASK_UPDATED"] = "task_updated";
|
|
404
404
|
NotifyType2["TASK_FAILED"] = "task_failed";
|
|
405
|
+
NotifyType2["OPERATION_CREATED"] = "operation_created";
|
|
405
406
|
})(NotifyType ||= {});
|
|
406
407
|
|
|
407
408
|
class LarkCliTaskNotifyHook {
|
|
@@ -411,6 +412,7 @@ class LarkCliTaskNotifyHook {
|
|
|
411
412
|
pluginName;
|
|
412
413
|
sourceId;
|
|
413
414
|
config;
|
|
415
|
+
lastNotifyTimestamps = new Map;
|
|
414
416
|
constructor(config = {}) {
|
|
415
417
|
this.name = config.pluginName || "LarkCliTaskNotifyHook";
|
|
416
418
|
this.priority = config.priority ?? 5;
|
|
@@ -420,7 +422,12 @@ class LarkCliTaskNotifyHook {
|
|
|
420
422
|
this.config = {
|
|
421
423
|
enabled: true,
|
|
422
424
|
priority: 5,
|
|
423
|
-
notifyTypes: [
|
|
425
|
+
notifyTypes: [
|
|
426
|
+
"task_created" /* TASK_CREATED */,
|
|
427
|
+
"task_updated" /* TASK_UPDATED */,
|
|
428
|
+
"task_completed" /* TASK_COMPLETED */,
|
|
429
|
+
"operation_created" /* OPERATION_CREATED */
|
|
430
|
+
],
|
|
424
431
|
...config
|
|
425
432
|
};
|
|
426
433
|
}
|
|
@@ -443,6 +450,9 @@ class LarkCliTaskNotifyHook {
|
|
|
443
450
|
case TaskHookPoints.AFTER_UPDATE:
|
|
444
451
|
await this.onAfterUpdate(ctx);
|
|
445
452
|
break;
|
|
453
|
+
case TaskHookPoints.OPERATION_AFTER_CREATE:
|
|
454
|
+
await this.onAfterOperationCreate(ctx);
|
|
455
|
+
break;
|
|
446
456
|
}
|
|
447
457
|
}
|
|
448
458
|
async onAfterCreate(ctx) {
|
|
@@ -456,12 +466,11 @@ class LarkCliTaskNotifyHook {
|
|
|
456
466
|
});
|
|
457
467
|
}
|
|
458
468
|
async onAfterUpdate(ctx) {
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
if (!innerData) {
|
|
469
|
+
const data = ctx.data;
|
|
470
|
+
if (!data) {
|
|
462
471
|
return;
|
|
463
472
|
}
|
|
464
|
-
const { task, changes } =
|
|
473
|
+
const { task, changes } = data;
|
|
465
474
|
if (!task) {
|
|
466
475
|
return;
|
|
467
476
|
}
|
|
@@ -489,6 +498,25 @@ class LarkCliTaskNotifyHook {
|
|
|
489
498
|
_hookContext: ctx
|
|
490
499
|
});
|
|
491
500
|
}
|
|
501
|
+
async onAfterOperationCreate(ctx) {
|
|
502
|
+
const { operation } = ctx.data;
|
|
503
|
+
if (!operation) {
|
|
504
|
+
logger2.debug("onAfterOperationCreate: operation is missing, skip");
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (!this.shouldNotify("operation_created" /* OPERATION_CREATED */)) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
if (this.shouldThrottleOperation(operation)) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
await this.sendNotify({
|
|
514
|
+
type: "operation_created" /* OPERATION_CREATED */,
|
|
515
|
+
title: this.getNotifyTitle("operation_created" /* OPERATION_CREATED */),
|
|
516
|
+
content: this.formatOperationCreated(operation),
|
|
517
|
+
_hookContext: ctx
|
|
518
|
+
});
|
|
519
|
+
}
|
|
492
520
|
async sendNotify(options) {
|
|
493
521
|
const { type, title, content, _hookContext } = options;
|
|
494
522
|
const env = getEnvContextOrEmpty();
|
|
@@ -594,6 +622,8 @@ ${content}`;
|
|
|
594
622
|
return "\uD83D\uDCCB 任务已更新";
|
|
595
623
|
case "task_failed" /* TASK_FAILED */:
|
|
596
624
|
return "❌ 任务执行失败";
|
|
625
|
+
case "operation_created" /* OPERATION_CREATED */:
|
|
626
|
+
return "\uD83D\uDCCC 操作记录";
|
|
597
627
|
default:
|
|
598
628
|
return "\uD83D\uDCEC 任务通知";
|
|
599
629
|
}
|
|
@@ -633,6 +663,43 @@ ${content}`;
|
|
|
633
663
|
lines.push(`- **变更**: ${changeKeys.join(", ")}`);
|
|
634
664
|
}
|
|
635
665
|
return lines.join(`
|
|
666
|
+
`);
|
|
667
|
+
}
|
|
668
|
+
shouldThrottleOperation(operation) {
|
|
669
|
+
const throttleMs = this.config.operationThrottleMs ?? 5000;
|
|
670
|
+
if (throttleMs <= 0) {
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
const key = `op:${operation.taskId}`;
|
|
674
|
+
const now = Date.now();
|
|
675
|
+
const lastTime = this.lastNotifyTimestamps.get(key);
|
|
676
|
+
if (lastTime && now - lastTime < throttleMs) {
|
|
677
|
+
logger2.debug(`[throttle] Skipping OPERATION_CREATED notify for task #${operation.taskId}, last notified ${now - lastTime}ms ago`);
|
|
678
|
+
return true;
|
|
679
|
+
}
|
|
680
|
+
this.lastNotifyTimestamps.set(key, now);
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
formatOperationCreated(operation) {
|
|
684
|
+
const lines = [];
|
|
685
|
+
if (operation.taskId !== undefined && operation.taskId !== null) {
|
|
686
|
+
lines.push(`- **任务 ID**: #${operation.taskId}`);
|
|
687
|
+
}
|
|
688
|
+
if (operation.actionType) {
|
|
689
|
+
lines.push(`- **操作类型**: ${operation.actionType}`);
|
|
690
|
+
}
|
|
691
|
+
if (operation.actionTitle) {
|
|
692
|
+
lines.push(`- **标题**: ${operation.actionTitle}`);
|
|
693
|
+
}
|
|
694
|
+
if (operation.actionDescription) {
|
|
695
|
+
const desc = String(operation.actionDescription);
|
|
696
|
+
const truncated = desc.substring(0, 200) + (desc.length > 200 ? "..." : "");
|
|
697
|
+
lines.push(`- **描述**: ${truncated}`);
|
|
698
|
+
}
|
|
699
|
+
if (operation.sessionId) {
|
|
700
|
+
lines.push(`- **Session**: \`${operation.sessionId}\``);
|
|
701
|
+
}
|
|
702
|
+
return lines.join(`
|
|
636
703
|
`);
|
|
637
704
|
}
|
|
638
705
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TaskTagPlugin,
|
|
3
3
|
createLarkCliTaskNotifyHook
|
|
4
|
-
} from "./roy-agent-core-
|
|
4
|
+
} from "./roy-agent-core-qqhbxq56.js";
|
|
5
5
|
import {
|
|
6
6
|
envKeyToConfigKey
|
|
7
7
|
} from "./roy-agent-core-qxhq8ven.js";
|
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
createEnvContext,
|
|
20
20
|
runWithEnvContext
|
|
21
21
|
} from "./roy-agent-core-y5d04fm3.js";
|
|
22
|
+
import {
|
|
23
|
+
TracedAs
|
|
24
|
+
} from "./roy-agent-core-k05v31rc.js";
|
|
22
25
|
import {
|
|
23
26
|
createLogger,
|
|
24
27
|
init_logger
|
|
@@ -27,6 +30,7 @@ import {
|
|
|
27
30
|
getTracerProvider
|
|
28
31
|
} from "./roy-agent-core-7z9b1fm8.js";
|
|
29
32
|
import {
|
|
33
|
+
__legacyDecorateClassTS,
|
|
30
34
|
__require
|
|
31
35
|
} from "./roy-agent-core-fs0mn2jk.js";
|
|
32
36
|
|
|
@@ -223,7 +227,11 @@ class LarkCliInstance {
|
|
|
223
227
|
return [plugin.hookPoint];
|
|
224
228
|
}
|
|
225
229
|
if (plugin.name && typeof plugin.execute === "function") {
|
|
226
|
-
return [
|
|
230
|
+
return [
|
|
231
|
+
"task:after.create",
|
|
232
|
+
"task:after.update",
|
|
233
|
+
"task:operation:after.create"
|
|
234
|
+
];
|
|
227
235
|
}
|
|
228
236
|
return [];
|
|
229
237
|
}
|
|
@@ -510,6 +518,15 @@ class LarkCliInstance {
|
|
|
510
518
|
});
|
|
511
519
|
}
|
|
512
520
|
}
|
|
521
|
+
__legacyDecorateClassTS([
|
|
522
|
+
TracedAs("lark-cli.loadPlugins", { recordParams: true, log: true })
|
|
523
|
+
], LarkCliInstance.prototype, "loadPlugins", null);
|
|
524
|
+
__legacyDecorateClassTS([
|
|
525
|
+
TracedAs("lark-cli.registerPluginHooks", { recordParams: true, log: true })
|
|
526
|
+
], LarkCliInstance.prototype, "registerPluginHooks", null);
|
|
527
|
+
__legacyDecorateClassTS([
|
|
528
|
+
TracedAs("lark-cli.handleEvent", { recordParams: true, log: true })
|
|
529
|
+
], LarkCliInstance.prototype, "handleEvent", null);
|
|
513
530
|
var larkCliHandler = {
|
|
514
531
|
type: "lark-cli",
|
|
515
532
|
validateConfig(config) {
|
|
@@ -98,6 +98,8 @@ class BaseEnvironment extends BaseComponent {
|
|
|
98
98
|
envEvent: context || { type: "workflow" },
|
|
99
99
|
sourceId: "workflow",
|
|
100
100
|
userId: context?.metadata?.userId || "",
|
|
101
|
+
replyChannel: existingCtx?.replyChannel,
|
|
102
|
+
pluginEnabled: existingCtx?.pluginEnabled,
|
|
101
103
|
agentContext: existingCtx?.agentContext ?? {}
|
|
102
104
|
};
|
|
103
105
|
return await runWithEnvContextAsync(workflowEnvContext, async () => {
|