@ai-setting/roy-agent-core 1.7.75 → 1.7.77
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/agent-component.js +2 -2
- package/dist/env/agent/index.js +2 -2
- package/dist/env/event-source/event-source-handlers.js +9 -8
- package/dist/env/event-source/index.js +10 -9
- package/dist/env/index.js +16 -15
- package/dist/env/prompt/index.js +4 -3
- package/dist/env/prompt/prompts-index.d.ts +11 -9
- package/dist/env/task/backend/index.js +45 -1
- package/dist/env/task/backend/task-store-backend.d.ts +12 -0
- package/dist/env/task/backend/types.d.ts +19 -0
- package/dist/env/task/delegate/delegate-tool.js +4 -3
- package/dist/env/task/delegate/index.js +4 -3
- package/dist/env/task/hooks/contexts.d.ts +12 -1
- package/dist/env/task/hooks/task-hook-points.d.ts +8 -3
- package/dist/env/task/index.d.ts +1 -0
- package/dist/env/task/index.js +17 -7
- package/dist/env/task/mcp/index.js +6 -2
- package/dist/env/task/mcp/task-mcp-server.d.ts +1 -1
- package/dist/env/task/plugins/fake-user-message-helper.d.ts +10 -2
- package/dist/env/task/plugins/index.d.ts +1 -0
- package/dist/env/task/plugins/index.js +18 -6
- package/dist/env/task/plugins/lark-card-patch-notifier.js +1 -1
- package/dist/env/task/plugins/task-op-watermark-plugin.d.ts +112 -0
- package/dist/env/task/prompt/index.js +2 -1
- package/dist/env/task/prompt/task-discipline.d.ts +1 -1
- package/dist/env/task/storage/index.js +2 -2
- package/dist/env/task/storage/sqlite-task-store.d.ts +54 -0
- package/dist/env/task/task-component.d.ts +95 -0
- package/dist/env/task/tools/cancel-tool.d.ts +12 -4
- package/dist/env/task/tools/completion-copy.d.ts +92 -0
- package/dist/env/task/tools/index.d.ts +1 -0
- package/dist/env/task/tools/index.js +5 -2
- package/dist/env/task/tools/operation/operation-types.d.ts +13 -13
- package/dist/env/task/tools/pre-complete-tool.d.ts +32 -0
- package/dist/env/task/tools/task-types.d.ts +49 -17
- package/dist/env/task/types.d.ts +13 -1
- package/dist/env/workflow/plugins/index.js +2 -2
- package/dist/env/workflow/types/event.d.ts +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +26 -16
- package/dist/shared/@ai-setting/{roy-agent-core-n9q1encx.js → roy-agent-core-0v27y99n.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-60jbrfye.js → roy-agent-core-3gpygqcx.js} +30 -6
- package/dist/shared/@ai-setting/roy-agent-core-4rtg69cn.js +26 -0
- package/dist/shared/@ai-setting/{roy-agent-core-djpq6yb0.js → roy-agent-core-9vhq7fvv.js} +6 -2
- package/dist/shared/@ai-setting/{roy-agent-core-3e6gg17d.js → roy-agent-core-9vxh6f8h.js} +169 -30
- package/dist/shared/@ai-setting/{roy-agent-core-jg65qnwa.js → roy-agent-core-aa2j7bk9.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-29b6hc39.js → roy-agent-core-cmprygrp.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-snvh4s2p.js → roy-agent-core-ew6qb5yx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-abqhkbn3.js → roy-agent-core-ezvpreqz.js} +23 -0
- package/dist/shared/@ai-setting/roy-agent-core-h21gngxf.js +247 -0
- package/dist/shared/@ai-setting/{roy-agent-core-p3zv1mx5.js → roy-agent-core-hd3n57zs.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-11shp00p.js → roy-agent-core-m46fe3x4.js} +21 -31
- package/dist/shared/@ai-setting/{roy-agent-core-ntq0gz7q.js → roy-agent-core-q813vafd.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-4gr3k7qg.js → roy-agent-core-rhtdspx6.js} +140 -29
- package/dist/shared/@ai-setting/{roy-agent-core-y7x2qzwc.js → roy-agent-core-rsn44n9y.js} +10 -6
- package/dist/shared/@ai-setting/{roy-agent-core-hnyk1by7.js → roy-agent-core-vffccgf6.js} +152 -33
- package/dist/shared/@ai-setting/{roy-agent-core-nmx9934r.js → roy-agent-core-w0qjeq2v.js} +1 -1
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-f77k3gqt.js +0 -71
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
} from "./roy-agent-core-na18zwj0.js";
|
|
4
4
|
import {
|
|
5
5
|
WORKFLOW_EXTRACT_PROMPT
|
|
6
|
-
} from "./roy-agent-core-
|
|
6
|
+
} from "./roy-agent-core-9vxh6f8h.js";
|
|
7
7
|
import {
|
|
8
8
|
createCompatibleDatabase,
|
|
9
9
|
init_sqlite_task_store
|
|
10
|
-
} from "./roy-agent-core-
|
|
10
|
+
} from "./roy-agent-core-ezvpreqz.js";
|
|
11
11
|
import {
|
|
12
12
|
TaskHookPoints
|
|
13
13
|
} from "./roy-agent-core-1pg0fepg.js";
|
|
@@ -24,13 +24,13 @@ import {
|
|
|
24
24
|
import {
|
|
25
25
|
LarkCardPatchNotifier,
|
|
26
26
|
humanizeValue
|
|
27
|
-
} from "./roy-agent-core-
|
|
27
|
+
} from "./roy-agent-core-w0qjeq2v.js";
|
|
28
28
|
import {
|
|
29
29
|
validateWorkflowDefinition
|
|
30
30
|
} from "./roy-agent-core-1v4g0d4x.js";
|
|
31
31
|
import {
|
|
32
32
|
enqueueToAddFakeUserMessage
|
|
33
|
-
} from "./roy-agent-core-
|
|
33
|
+
} from "./roy-agent-core-h21gngxf.js";
|
|
34
34
|
import {
|
|
35
35
|
BasePlugin
|
|
36
36
|
} from "./roy-agent-core-az13yzmc.js";
|
|
@@ -1515,8 +1515,8 @@ class LayaCompletionPlugin {
|
|
|
1515
1515
|
logger5.warn("[laya-completion] taskComponent not injected — skip");
|
|
1516
1516
|
return;
|
|
1517
1517
|
}
|
|
1518
|
-
if (ctx.terminalStatus !== "completed") {
|
|
1519
|
-
logger5.debug(`[laya-completion] terminalStatus=${ctx.terminalStatus} — skip (only completed)`);
|
|
1518
|
+
if (ctx.terminalStatus !== "completed" && ctx.terminalStatus !== "to_validate") {
|
|
1519
|
+
logger5.debug(`[laya-completion] terminalStatus=${ctx.terminalStatus} — skip (only completed / to_validate)`);
|
|
1520
1520
|
return;
|
|
1521
1521
|
}
|
|
1522
1522
|
const task = ctx.task;
|
|
@@ -2116,6 +2116,10 @@ class LarkCliTaskNotifyHook {
|
|
|
2116
2116
|
return;
|
|
2117
2117
|
if (!this.isCardModeEnabled())
|
|
2118
2118
|
return;
|
|
2119
|
+
const terminalStatus = data.terminalStatus;
|
|
2120
|
+
if (terminalStatus === "to_validate" || task.status === "to_validate") {
|
|
2121
|
+
return;
|
|
2122
|
+
}
|
|
2119
2123
|
await this.sendCardFinish(task);
|
|
2120
2124
|
}
|
|
2121
2125
|
async onAfterDelete(ctx) {
|
|
@@ -3,11 +3,16 @@ import {
|
|
|
3
3
|
NEW_TASK_ID_PLACEHOLDER
|
|
4
4
|
} from "./roy-agent-core-tr3ep81v.js";
|
|
5
5
|
import {
|
|
6
|
+
TASK_DISCIPLINE_GOALS
|
|
7
|
+
} from "./roy-agent-core-m46fe3x4.js";
|
|
8
|
+
import {
|
|
9
|
+
TASK_ARCHIVED_STATUS_WORD,
|
|
10
|
+
TASK_CANCELLED_STATUS_WORD,
|
|
6
11
|
TASK_COMPLETE_ITEM_BY_ITEM,
|
|
7
12
|
TASK_COMPLETE_VERIFY_DUTY,
|
|
8
13
|
TASK_COMPLETION_HINT_ANCHOR,
|
|
9
|
-
|
|
10
|
-
} from "./roy-agent-core-
|
|
14
|
+
TERMINAL_NON_ACCEPTABLE_STATUSES
|
|
15
|
+
} from "./roy-agent-core-4rtg69cn.js";
|
|
11
16
|
import {
|
|
12
17
|
getEnvContextOrEmpty,
|
|
13
18
|
init_env_context,
|
|
@@ -63,7 +68,7 @@ var GetTaskToolSchema = withLegacyTaskId({
|
|
|
63
68
|
include_operations: z.boolean().optional().default(true).describe("Include operation records (milestones / process log) with the task. " + "Defaults to true — the task's operation history is part of its detail. " + "Pass false for a lean task-only response.")
|
|
64
69
|
});
|
|
65
70
|
var ListTasksToolSchema = z.object({
|
|
66
|
-
status: z.enum(["todo", "active", "completed", "paused", "cancelled", "archived"]).optional(),
|
|
71
|
+
status: z.enum(["todo", "active", "to_validate", "completed", "paused", "cancelled", "archived"]).optional(),
|
|
67
72
|
priority: z.enum(["low", "medium", "high"]).optional(),
|
|
68
73
|
type: z.enum(["normal", "cycle", "longterm"]).optional().describe("Filter by task type"),
|
|
69
74
|
limit: z.number().optional().default(20),
|
|
@@ -75,7 +80,7 @@ var SearchTasksToolSchema = z.object({
|
|
|
75
80
|
keywords: z.array(z.string()).describe("关键词列表(AND 逻辑,匹配 title/description/goals/tags/operations)"),
|
|
76
81
|
limit: z.number().optional().default(20).describe("返回数量"),
|
|
77
82
|
offset: z.number().optional().default(0).describe("偏移量"),
|
|
78
|
-
status: z.enum(["todo", "active", "completed", "paused", "cancelled", "archived"]).optional().describe("按状态筛选"),
|
|
83
|
+
status: z.enum(["todo", "active", "to_validate", "completed", "paused", "cancelled", "archived"]).optional().describe("按状态筛选"),
|
|
79
84
|
priority: z.enum(["low", "medium", "high"]).optional().describe("按优先级筛选"),
|
|
80
85
|
type: z.enum(["normal", "cycle", "longterm"]).optional().describe("按类型筛选"),
|
|
81
86
|
exclude_task_id: z.number().optional().describe("排除的 task ID"),
|
|
@@ -85,7 +90,7 @@ var SearchTasksToolSchema = z.object({
|
|
|
85
90
|
var UpdateTaskToolSchema = withLegacyTaskId({
|
|
86
91
|
title: z.string().optional(),
|
|
87
92
|
description: z.string().optional(),
|
|
88
|
-
status: z.enum(["todo", "active", "completed", "paused", "cancelled", "archived"]).optional(),
|
|
93
|
+
status: z.enum(["todo", "active", "to_validate", "completed", "paused", "cancelled", "archived"]).optional(),
|
|
89
94
|
priority: z.enum(["low", "medium", "high"]).optional(),
|
|
90
95
|
type: z.enum(["normal", "cycle", "longterm"]).optional().describe("Task type"),
|
|
91
96
|
progress: z.number().min(0).max(100).optional(),
|
|
@@ -100,8 +105,10 @@ var UpdateTaskToolSchema = withLegacyTaskId({
|
|
|
100
105
|
var DeleteTaskToolSchema = z.object({
|
|
101
106
|
task_id: z.number().describe("Task ID")
|
|
102
107
|
});
|
|
103
|
-
var CompleteTaskToolSchema = withLegacyTaskId({
|
|
104
|
-
|
|
108
|
+
var CompleteTaskToolSchema = withLegacyTaskId({});
|
|
109
|
+
var PreCompleteTaskToolSchema = withLegacyTaskId({
|
|
110
|
+
deliverable_storage_path: z.string().optional().describe("交付物的寻址地址(路径 / URL / 分支名等)。" + "会持久化到 task.context.deliverable_storage_path," + "并写入 operation 记录(Deliverable 行),供验收方 task_complete 时逐条对照。"),
|
|
111
|
+
current_status: z.string().optional().describe("本次交付的进展摘要(可选)。" + "会拼进「待验证:」文案,作为任务当前状态展示给验收方(default agent)。")
|
|
105
112
|
});
|
|
106
113
|
var CancelTaskToolSchema = withLegacyTaskId({
|
|
107
114
|
reason: z.string().optional().describe("取消原因(可选)。会写入该任务的 operation 记录,便于事后追溯验收结论。")
|
|
@@ -116,7 +123,7 @@ var BatchDeleteToolSchema = z.object({
|
|
|
116
123
|
var TreeTasksToolSchema = z.object({
|
|
117
124
|
depth: z.number().optional().default(2).describe("树的展开深度。默认 2 (根 + 一层子任务 + 二层孙任务)。" + "0 = 只返回根任务,不展开任何子节点。" + "-1 或负数 = 无限层级(全部展开)。"),
|
|
118
125
|
parent_task_id: z.number().optional().describe("只看指定父任务的子树。不传则从所有根任务(forest)开始。"),
|
|
119
|
-
status: z.enum(["todo", "active", "completed", "paused", "cancelled", "archived"]).optional().describe("按状态过滤(与 task_list 一致)。"),
|
|
126
|
+
status: z.enum(["todo", "active", "to_validate", "completed", "paused", "cancelled", "archived"]).optional().describe("按状态过滤(与 task_list 一致)。"),
|
|
120
127
|
priority: z.enum(["low", "medium", "high"]).optional().describe("按优先级过滤。"),
|
|
121
128
|
type: z.enum(["normal", "cycle", "longterm"]).optional().describe("按任务类型过滤。"),
|
|
122
129
|
include_archived: z.boolean().optional().default(false).describe("是否包含已归档任务(默认 false,与 task_list 一致)。")
|
|
@@ -702,7 +709,10 @@ function batchArchiveTaskTool(taskComponent) {
|
|
|
702
709
|
let archivedCount = 0;
|
|
703
710
|
for (const taskId of taskIds) {
|
|
704
711
|
try {
|
|
705
|
-
const task = await taskComponent.updateTask(taskId, {
|
|
712
|
+
const task = await taskComponent.updateTask(taskId, {
|
|
713
|
+
status: "archived",
|
|
714
|
+
current_status: params.reason ? `${TASK_ARCHIVED_STATUS_WORD}:${params.reason}` : TASK_ARCHIVED_STATUS_WORD
|
|
715
|
+
});
|
|
706
716
|
if (task) {
|
|
707
717
|
await taskComponent.createOperation({
|
|
708
718
|
taskId,
|
|
@@ -940,7 +950,11 @@ init_env_context();
|
|
|
940
950
|
init_logger();
|
|
941
951
|
var logger4 = createLogger("task:tools:complete");
|
|
942
952
|
var TASK_COMPLETE_DESCRIPTION = `
|
|
943
|
-
|
|
953
|
+
Final acceptance of a submitted task: set status=completed, progress=100
|
|
954
|
+
(two-phase acceptance, Task #5073).
|
|
955
|
+
|
|
956
|
+
**Who should call this** — the **acceptance side** (default agent). The
|
|
957
|
+
executor (sub-agent) has NO permission to call it (deniedTools, Task #5007).
|
|
944
958
|
|
|
945
959
|
**Before calling this tool**, you MUST:
|
|
946
960
|
|
|
@@ -968,21 +982,27 @@ Mark a task as completed (progress=100, status=completed). Creates an operation
|
|
|
968
982
|
(milestone_type=decision) — the reason **must** land in the
|
|
969
983
|
operation record (必须落到操作记录里), not merely a line in
|
|
970
984
|
your final report (不能只在报告里带一句).
|
|
971
|
-
3.
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
-
|
|
975
|
-
|
|
976
|
-
- Cloud drive URL (e.g., https://my.feishu.cn/file/abc)
|
|
977
|
-
- Or any other locator that points to where the work product lives
|
|
978
|
-
|
|
979
|
-
The \`deliverable_storage_path\` will be persisted to the task's \`context.deliverable_storage_path\` for future reference and traceability.
|
|
985
|
+
3. Deliverables were already submitted by the executor via
|
|
986
|
+
\`task_pre_complete\` (they live in \`context.deliverable_storage_path\`
|
|
987
|
+
and the operation trail — Task #5073 design: task_complete takes **no**
|
|
988
|
+
deliverable parameter). Cross-check them in step 2; do NOT ask the
|
|
989
|
+
executor to resubmit.
|
|
980
990
|
|
|
981
991
|
**Restrictions**:
|
|
982
992
|
- Cannot complete cycle-type tasks (they are periodic). Use \`task_update\` to reset progress instead.
|
|
983
993
|
- Marks the task as 100% complete; use \`task_update\` to record partial progress first if needed.
|
|
984
994
|
|
|
985
|
-
**
|
|
995
|
+
**Side effects**:
|
|
996
|
+
- Sets \`status = "completed"\`, \`progress = 100\` **and refreshes \`current_status\`**
|
|
997
|
+
to the completed wording. You do **NOT** need a follow-up
|
|
998
|
+
\`task_update(current_status=...)\` call — a task must never keep a stale
|
|
999
|
+
pre-completion progress sentence (e.g. "paused, not committed") that would
|
|
1000
|
+
contradict \`status = "completed"\`.
|
|
1001
|
+
- The goal-check decision model does **NOT** run here — it already ran at
|
|
1002
|
+
\`task_pre_complete\` time (Task #5073 design v2). This tool is the final
|
|
1003
|
+
state commit by the acceptance side.
|
|
1004
|
+
- Cannot complete a task that is already in a terminal state (cancelled /
|
|
1005
|
+
archived) — reopen it first via \`task_update(status="active")\`.
|
|
986
1006
|
`.trim();
|
|
987
1007
|
function completeTaskTool(taskComponent) {
|
|
988
1008
|
return {
|
|
@@ -1010,7 +1030,18 @@ function completeTaskTool(taskComponent) {
|
|
|
1010
1030
|
metadata: { execution_time_ms: 0 }
|
|
1011
1031
|
};
|
|
1012
1032
|
}
|
|
1013
|
-
const
|
|
1033
|
+
const TERMINAL_NON_ACCEPTABLE = new Set([
|
|
1034
|
+
...TERMINAL_NON_ACCEPTABLE_STATUSES
|
|
1035
|
+
]);
|
|
1036
|
+
if (TERMINAL_NON_ACCEPTABLE.has(currentTask.status)) {
|
|
1037
|
+
return {
|
|
1038
|
+
success: false,
|
|
1039
|
+
output: "",
|
|
1040
|
+
error: `Cannot complete task #${params.task_id}: it is already in terminal status "${currentTask.status}". Reopen it first via task_update(status="active") if acceptance should proceed.`,
|
|
1041
|
+
metadata: { execution_time_ms: 0 }
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
const task = await taskComponent.completeTask(params.task_id, sessionId);
|
|
1014
1045
|
if (!task) {
|
|
1015
1046
|
return {
|
|
1016
1047
|
success: false,
|
|
@@ -1020,12 +1051,10 @@ function completeTaskTool(taskComponent) {
|
|
|
1020
1051
|
};
|
|
1021
1052
|
}
|
|
1022
1053
|
setCurrentTaskId(undefined);
|
|
1023
|
-
logger4.info(`[completeTask] Trace: Task #${params.task_id} completed
|
|
1054
|
+
logger4.info(`[completeTask] Trace: Task #${params.task_id} completed (acceptance committed), currentTaskId cleared from EnvContext`);
|
|
1024
1055
|
return {
|
|
1025
1056
|
success: true,
|
|
1026
|
-
output:
|
|
1027
|
-
Deliverable (context + operation): ${params.deliverable_storage_path}` : `Task completed: #${task.id} - ${task.title}
|
|
1028
|
-
Deliverable: (no path provided)`,
|
|
1057
|
+
output: `Task completed: #${task.id} - ${task.title}`,
|
|
1029
1058
|
metadata: { execution_time_ms: 0, task }
|
|
1030
1059
|
};
|
|
1031
1060
|
} catch (error) {
|
|
@@ -1044,13 +1073,17 @@ init_logger();
|
|
|
1044
1073
|
var logger5 = createLogger("tool:cancel-task");
|
|
1045
1074
|
var NON_CANCELLABLE_STATUSES = new Set(["completed", "cancelled", "archived"]);
|
|
1046
1075
|
var TASK_CANCEL_DESCRIPTION = `
|
|
1047
|
-
Cancel a task (task.status = "cancelled"). This is the **acceptance-side** cancel
|
|
1048
|
-
use it when the work is abandoned, the user asked to stop, or acceptance failed.
|
|
1076
|
+
Cancel a task (task.status = "cancelled"). This is the **acceptance-side** cancel.
|
|
1049
1077
|
|
|
1050
|
-
**When to use
|
|
1051
|
-
- The user asks to cancel / stop / drop the task
|
|
1052
|
-
|
|
1053
|
-
|
|
1078
|
+
**When to use** — ONLY when the user explicitly asks (用户明令):
|
|
1079
|
+
- The user asks to cancel / stop / drop the task (用户明令取消 / 停掉 / 放弃这个任务)
|
|
1080
|
+
|
|
1081
|
+
**When NOT to use**:
|
|
1082
|
+
- ❌ A sub-agent failed / timed out / went off-track — that is NOT a cancellation.
|
|
1083
|
+
Find the root cause, propose a fix, and re-delegate (with \`sub_session_id\` to resume).
|
|
1084
|
+
If it truly cannot be moved forward, report the situation to the user and **wait for
|
|
1085
|
+
the user's decision** — do NOT cancel it on your own.
|
|
1086
|
+
- ❌ Acceptance found gaps but re-delegation is still possible — re-delegate instead.
|
|
1054
1087
|
|
|
1055
1088
|
**What it does NOT do**:
|
|
1056
1089
|
- It does **NOT** stop a running background process — that is \`stop_task\`
|
|
@@ -1060,6 +1093,9 @@ use it when the work is abandoned, the user asked to stop, or acceptance failed.
|
|
|
1060
1093
|
**Side effects**:
|
|
1061
1094
|
- Sets \`status = "cancelled"\` and fires the task terminal-state hooks
|
|
1062
1095
|
(notifications / card state machine converge to the cancelled state).
|
|
1096
|
+
- Also refreshes \`current_status\` to the cancelled wording (with your \`reason\`
|
|
1097
|
+
appended when given) — the task no longer keeps a stale pre-cancel progress
|
|
1098
|
+
sentence that would contradict \`status = "cancelled"\`.
|
|
1063
1099
|
- Writes an operation record so the cancellation reason stays auditable.
|
|
1064
1100
|
- A cancelled task can be reopened later with \`task_update(status="active")\`.
|
|
1065
1101
|
|
|
@@ -1094,7 +1130,8 @@ function cancelTaskTool(taskComponent) {
|
|
|
1094
1130
|
};
|
|
1095
1131
|
}
|
|
1096
1132
|
const task = await taskComponent.updateTask(params.task_id, {
|
|
1097
|
-
status: "cancelled"
|
|
1133
|
+
status: "cancelled",
|
|
1134
|
+
current_status: params.reason ? `${TASK_CANCELLED_STATUS_WORD}:${params.reason}` : TASK_CANCELLED_STATUS_WORD
|
|
1098
1135
|
});
|
|
1099
1136
|
if (!task) {
|
|
1100
1137
|
return {
|
|
@@ -1128,6 +1165,88 @@ function cancelTaskTool(taskComponent) {
|
|
|
1128
1165
|
}
|
|
1129
1166
|
};
|
|
1130
1167
|
}
|
|
1168
|
+
// src/env/task/tools/pre-complete-tool.ts
|
|
1169
|
+
init_logger();
|
|
1170
|
+
var logger6 = createLogger("task:tools:pre-complete");
|
|
1171
|
+
var TASK_PRE_COMPLETE_DESCRIPTION = `
|
|
1172
|
+
Submit a task for acceptance (two-phase acceptance, Task #5073).
|
|
1173
|
+
|
|
1174
|
+
**Who should call this** — the **executor** (sub-agent) when it believes
|
|
1175
|
+
the work is done and deliverables are ready.
|
|
1176
|
+
|
|
1177
|
+
**What it does**:
|
|
1178
|
+
- Sets \`status = "to_validate"\` (待验证) — the task enters the
|
|
1179
|
+
acceptance queue. This is **NOT** a terminal state.
|
|
1180
|
+
- Persists \`deliverable_storage_path\` to \`task.context.deliverable_storage_path\`
|
|
1181
|
+
and writes a \`Deliverable: <path>\` line into the operation trail.
|
|
1182
|
+
- Refreshes \`current_status\` to the to-validate wording
|
|
1183
|
+
(with your progress summary appended when given).
|
|
1184
|
+
- Creates an operation record so the submission stays auditable.
|
|
1185
|
+
|
|
1186
|
+
**What it does NOT do**:
|
|
1187
|
+
- It does **NOT** mark the task completed — final acceptance
|
|
1188
|
+
(\`task_complete\`) belongs to the **default agent** (验收权分离, Task #5007).
|
|
1189
|
+
|
|
1190
|
+
**Goal self-check (design v2)**:
|
|
1191
|
+
- Submitting **does** fire the completion goal-check hook once
|
|
1192
|
+
(\`terminalStatus="to_validate"\`) as a self-check gate — the
|
|
1193
|
+
decision model reviews your goals/operations at submission time.
|
|
1194
|
+
If it produces a hint, read it and address the gaps **before**
|
|
1195
|
+
ending your turn. The final acceptance (\`task_complete\`) does
|
|
1196
|
+
**not** re-run the goal check.
|
|
1197
|
+
|
|
1198
|
+
**After calling**:
|
|
1199
|
+
- Push progress to 100 via \`task_update(progress=100)\` if not already,
|
|
1200
|
+
then **end your turn and return the result** to the main agent.
|
|
1201
|
+
- The default agent will pick up the notification, verify the goals
|
|
1202
|
+
item-by-item, and call \`task_complete\` (or re-delegate on gaps).
|
|
1203
|
+
|
|
1204
|
+
**Parameters**:
|
|
1205
|
+
- \`task_id\` (required): the task to submit
|
|
1206
|
+
- \`deliverable_storage_path\` (optional): where the work product lives
|
|
1207
|
+
(file path / Feishu doc URL / git branch / PR URL ...)
|
|
1208
|
+
- \`current_status\` (optional): a one-line progress summary shown to the
|
|
1209
|
+
acceptance side (e.g. "实现完成,测试全绿")
|
|
1210
|
+
|
|
1211
|
+
**Restrictions**:
|
|
1212
|
+
- Cannot pre-complete cycle-type tasks (they are periodic).
|
|
1213
|
+
`.trim();
|
|
1214
|
+
function preCompleteTaskTool(taskComponent) {
|
|
1215
|
+
return {
|
|
1216
|
+
name: "task_pre_complete",
|
|
1217
|
+
description: TASK_PRE_COMPLETE_DESCRIPTION,
|
|
1218
|
+
parameters: PreCompleteTaskToolSchema,
|
|
1219
|
+
execute: async (args, ctx) => {
|
|
1220
|
+
const params = PreCompleteTaskToolSchema.parse(args);
|
|
1221
|
+
const sessionId = ctx.session_id || "unknown";
|
|
1222
|
+
try {
|
|
1223
|
+
const task = await taskComponent.preCompleteTask(params.task_id, sessionId, params.deliverable_storage_path, params.current_status);
|
|
1224
|
+
if (!task) {
|
|
1225
|
+
return {
|
|
1226
|
+
success: false,
|
|
1227
|
+
output: "",
|
|
1228
|
+
error: `Task not found: ${params.task_id}`,
|
|
1229
|
+
metadata: { execution_time_ms: 0 }
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
return {
|
|
1233
|
+
success: true,
|
|
1234
|
+
output: params.deliverable_storage_path ? `Task submitted for acceptance (to_validate): #${task.id} - ${task.title}
|
|
1235
|
+
Deliverable (context + operation): ${params.deliverable_storage_path}` : `Task submitted for acceptance (to_validate): #${task.id} - ${task.title}
|
|
1236
|
+
Deliverable: (no path provided)`,
|
|
1237
|
+
metadata: { execution_time_ms: 0, task }
|
|
1238
|
+
};
|
|
1239
|
+
} catch (error) {
|
|
1240
|
+
return {
|
|
1241
|
+
success: false,
|
|
1242
|
+
output: "",
|
|
1243
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1244
|
+
metadata: { execution_time_ms: 0 }
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1131
1250
|
// src/env/task/tools/task-tree-tool.ts
|
|
1132
1251
|
function compareTasksDesc(a, b) {
|
|
1133
1252
|
if (a.updatedAt < b.updatedAt)
|
|
@@ -1266,4 +1385,4 @@ function treeTasksTool(taskComponent) {
|
|
|
1266
1385
|
}
|
|
1267
1386
|
};
|
|
1268
1387
|
}
|
|
1269
|
-
export { createTaskTool, getTaskTool, listTasksTool, searchTasksTool, batchArchiveTaskTool, batchDeleteTaskTool, updateTaskTool, deleteTaskTool, completeTaskTool, cancelTaskTool, treeTasksTool };
|
|
1388
|
+
export { createTaskTool, getTaskTool, listTasksTool, searchTasksTool, batchArchiveTaskTool, batchDeleteTaskTool, updateTaskTool, deleteTaskTool, completeTaskTool, cancelTaskTool, preCompleteTaskTool, treeTasksTool };
|
|
@@ -60,7 +60,7 @@ function sanitizeInlineText(text, maxLen = 300) {
|
|
|
60
60
|
if (!text)
|
|
61
61
|
return "";
|
|
62
62
|
const flat = text.replace(/\r\n?/g, `
|
|
63
|
-
`).replace(/^#{1,6}\s+/gm, "").replace(/^\s*[-*+]\s+/gm, "· ").replace(/^\s*\d+\.\s+/gm, "· ").replace(/\*\*/g, "").replace(/`/g, "").replace(/\n+/g, " · ").replace(/\s{2,}/g, " ").replace(/(?:\s*·\s*){2,}/g, " · ").replace(/^(\s*·\s*)+/, "").replace(/(\s*·\s*)+$/, "").trim();
|
|
63
|
+
`).replace(/^#{1,6}\s+/gm, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, (_m, alt) => alt.trim() ? `${alt.trim()}[图片]` : "[图片]").replace(/^\s*[-*+]\s+/gm, "· ").replace(/^\s*\d+\.\s+/gm, "· ").replace(/\*\*/g, "").replace(/`/g, "").replace(/\n+/g, " · ").replace(/\s{2,}/g, " ").replace(/(?:\s*·\s*){2,}/g, " · ").replace(/^(\s*·\s*)+/, "").replace(/(\s*·\s*)+$/, "").trim();
|
|
64
64
|
return flat.length <= maxLen ? flat : `${flat.slice(0, maxLen)}…`;
|
|
65
65
|
}
|
|
66
66
|
var HEAD_TITLE_MAX_WIDTH = 40;
|
package/package.json
CHANGED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
init_decorator,
|
|
3
|
-
wrapFunction
|
|
4
|
-
} from "./roy-agent-core-qq96p0tj.js";
|
|
5
|
-
|
|
6
|
-
// src/env/task/plugins/fake-user-message-helper.ts
|
|
7
|
-
init_decorator();
|
|
8
|
-
var KIND_FIELD = "__fakeUserMessageKind";
|
|
9
|
-
function ensureMetadata(toolResult) {
|
|
10
|
-
if (!toolResult)
|
|
11
|
-
return;
|
|
12
|
-
if (!toolResult.result)
|
|
13
|
-
toolResult.result = {};
|
|
14
|
-
if (!toolResult.result.metadata)
|
|
15
|
-
toolResult.result.metadata = {};
|
|
16
|
-
return toolResult.result.metadata;
|
|
17
|
-
}
|
|
18
|
-
function stringContent(msg) {
|
|
19
|
-
const c = msg?.content;
|
|
20
|
-
return typeof c === "string" ? c : JSON.stringify(c);
|
|
21
|
-
}
|
|
22
|
-
function enqueueToAddFakeUserMessageImpl(toolResult, newMsg, newKind) {
|
|
23
|
-
const meta = ensureMetadata(toolResult);
|
|
24
|
-
if (!meta)
|
|
25
|
-
return { willMerge: false, finalKind: newKind };
|
|
26
|
-
const existing = meta.toAddFakeUserMessage;
|
|
27
|
-
const existingKind = meta[KIND_FIELD];
|
|
28
|
-
if (!existing) {
|
|
29
|
-
meta.toAddFakeUserMessage = newMsg;
|
|
30
|
-
meta[KIND_FIELD] = newKind;
|
|
31
|
-
return { willMerge: false, finalKind: newKind };
|
|
32
|
-
}
|
|
33
|
-
let merged;
|
|
34
|
-
if (newKind === "max-iter") {
|
|
35
|
-
merged = {
|
|
36
|
-
role: "user",
|
|
37
|
-
content: `${stringContent(existing)}
|
|
38
|
-
|
|
39
|
-
${stringContent(newMsg)}`
|
|
40
|
-
};
|
|
41
|
-
} else if (newKind === "delegate" && existingKind === "max-iter") {
|
|
42
|
-
merged = {
|
|
43
|
-
role: "user",
|
|
44
|
-
content: `${stringContent(newMsg)}
|
|
45
|
-
|
|
46
|
-
${stringContent(existing)}`
|
|
47
|
-
};
|
|
48
|
-
} else {
|
|
49
|
-
merged = {
|
|
50
|
-
role: "user",
|
|
51
|
-
content: `${stringContent(existing)}
|
|
52
|
-
|
|
53
|
-
${stringContent(newMsg)}`
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
meta.toAddFakeUserMessage = merged;
|
|
57
|
-
const finalKind = newKind === "max-iter" || existingKind === "max-iter" ? "max-iter" : newKind;
|
|
58
|
-
meta[KIND_FIELD] = finalKind;
|
|
59
|
-
return { willMerge: true, finalKind };
|
|
60
|
-
}
|
|
61
|
-
var enqueueToAddFakeUserMessage = wrapFunction(enqueueToAddFakeUserMessageImpl, "plugin.fake-user-message.enqueue", {
|
|
62
|
-
recordParams: false,
|
|
63
|
-
recordResult: false,
|
|
64
|
-
log: true,
|
|
65
|
-
resultFilter: (result) => ({
|
|
66
|
-
"fake-user-message.will_merge": result.willMerge,
|
|
67
|
-
"fake-user-message.final_kind": result.finalKind
|
|
68
|
-
})
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
export { enqueueToAddFakeUserMessage };
|