forked from openclaw/openclaw
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask-status.test.ts
More file actions
146 lines (127 loc) · 4.67 KB
/
Copy pathtask-status.test.ts
File metadata and controls
146 lines (127 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { describe, expect, it } from "vitest";
import type { TaskRecord } from "./task-registry.types.js";
import {
buildTaskStatusSnapshot,
formatTaskStatusDetail,
formatTaskStatusTitle,
sanitizeTaskStatusText,
} from "./task-status.js";
const NOW = 1_000_000_000_000;
function makeTask(overrides: Partial<TaskRecord>): TaskRecord {
return {
taskId: "task-1",
runId: "run-1",
task: "default task",
runtime: "subagent",
status: "running",
requesterSessionKey: "agent:main:main",
ownerKey: "agent:main:main",
scopeKind: "session",
createdAt: NOW - 1_000,
deliveryStatus: "pending",
notifyPolicy: "done_only",
...overrides,
};
}
describe("task status snapshot", () => {
it("keeps old active tasks active without maintenance reconciliation", () => {
const staleButActive = makeTask({
createdAt: NOW - 10 * 60_000,
startedAt: NOW - 10 * 60_000,
lastEventAt: NOW - 10 * 60_000,
progressSummary: "still running",
});
const snapshot = buildTaskStatusSnapshot([staleButActive], { now: NOW });
expect(snapshot.activeCount).toBe(1);
expect(snapshot.recentFailureCount).toBe(0);
expect(snapshot.focus?.status).toBe("running");
expect(snapshot.focus?.taskId).toBe("task-1");
});
it("filters tasks whose cleanupAfter has expired", () => {
const expired = makeTask({
status: "succeeded",
endedAt: NOW - 60_000,
cleanupAfter: NOW - 1,
});
const snapshot = buildTaskStatusSnapshot([expired], { now: NOW });
expect(snapshot.totalCount).toBe(0);
expect(snapshot.focus).toBeUndefined();
});
});
describe("task status formatting", () => {
it("truncates long task titles and details", () => {
const task = makeTask({
task: "This is a deliberately long task prompt that should never be emitted in full because it may include internal instructions and file paths.",
progressSummary:
"This progress detail is also intentionally long so the status line proves it truncates verbose task context instead of dumping a wall of text.",
});
expect(formatTaskStatusTitle(task)).toContain(
"This is a deliberately long task prompt that should never be emitted in full",
);
expect(formatTaskStatusTitle(task).endsWith("…")).toBe(true);
expect(formatTaskStatusDetail(task)).toContain(
"This progress detail is also intentionally long so the status line proves it truncates verbose task context",
);
expect(formatTaskStatusDetail(task)?.endsWith("…")).toBe(true);
});
it("strips leaked internal runtime context from task details", () => {
const task = makeTask({
status: "failed",
error: [
"OpenClaw runtime context (internal):",
"This context is runtime-generated, not user-authored. Keep internal details private.",
"",
"[Internal task completion event]",
"source: subagent",
].join("\n"),
});
expect(formatTaskStatusDetail(task)).toBeUndefined();
});
it("sanitizes task titles before truncation", () => {
const task = makeTask({
task: [
"OpenClaw runtime context (internal):",
"This context is runtime-generated, not user-authored. Keep internal details private.",
"",
"[Internal task completion event]",
"source: subagent",
].join("\n"),
});
expect(formatTaskStatusTitle(task)).toBe("Background task");
});
it("falls back to sanitized terminal summary when the error strips empty", () => {
const task = makeTask({
status: "failed",
error: [
"OpenClaw runtime context (internal):",
"This context is runtime-generated, not user-authored. Keep internal details private.",
"",
"[Internal task completion event]",
"source: subagent",
].join("\n"),
terminalSummary: "Needs login approval.",
});
expect(formatTaskStatusDetail(task)).toBe("Needs login approval.");
});
it("redacts raw exec denial detail from terminal task status", () => {
const task = makeTask({
status: "succeeded",
terminalOutcome: "blocked",
terminalSummary: "Exec denied (gateway id=req-1, approval-timeout): bash -lc ls",
});
expect(formatTaskStatusDetail(task)).toBe("Command did not run: approval timed out.");
});
it("sanitizes free-form task status text for reuse in other surfaces", () => {
expect(
sanitizeTaskStatusText(
[
"OpenClaw runtime context (internal):",
"This context is runtime-generated, not user-authored. Keep internal details private.",
"",
"[Internal task completion event]",
"source: subagent",
].join("\n"),
),
).toBe("");
});
});