@openclaw-china/shared 2026.3.4-2 → 2026.3.5
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/package.json +1 -1
- package/src/cron/index.test.ts +57 -0
- package/src/cron/index.ts +22 -7
package/package.json
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
appendCronHiddenPrompt,
|
|
4
|
+
applyCronHiddenPromptToContext,
|
|
5
|
+
shouldInjectCronHiddenPrompt,
|
|
6
|
+
splitCronHiddenPrompt,
|
|
7
|
+
} from "./index.js";
|
|
8
|
+
|
|
9
|
+
describe("cron hidden prompt", () => {
|
|
10
|
+
it("injects fixed delivery guidance for reminder-like messages", () => {
|
|
11
|
+
const text = "请帮我每小时提醒喝水";
|
|
12
|
+
const next = appendCronHiddenPrompt(text);
|
|
13
|
+
|
|
14
|
+
expect(shouldInjectCronHiddenPrompt(text)).toBe(true);
|
|
15
|
+
expect(next).not.toBe(text);
|
|
16
|
+
expect(next).toContain('sessionTarget="isolated"');
|
|
17
|
+
expect(next).toContain('payload.kind="agentTurn"');
|
|
18
|
+
expect(next).toContain("Use the built-in cron tool (action=add/update)");
|
|
19
|
+
expect(next).toContain("payload.message must be plain user-visible reminder text only");
|
|
20
|
+
expect(next).toContain('delivery.mode="announce"');
|
|
21
|
+
expect(next).toContain("delivery.channel=<OriginatingChannel>");
|
|
22
|
+
expect(next).toContain("delivery.to=<OriginatingTo>");
|
|
23
|
+
expect(next).toContain('Never set delivery.channel="last"');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("does not inject for documentation-style questions", () => {
|
|
27
|
+
const text = "cron 文档怎么用?";
|
|
28
|
+
const next = appendCronHiddenPrompt(text);
|
|
29
|
+
|
|
30
|
+
expect(shouldInjectCronHiddenPrompt(text)).toBe(false);
|
|
31
|
+
expect(next).toBe(text);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("is idempotent when called repeatedly", () => {
|
|
35
|
+
const text = "每分钟提醒我伸展一下";
|
|
36
|
+
const once = appendCronHiddenPrompt(text);
|
|
37
|
+
const twice = appendCronHiddenPrompt(once);
|
|
38
|
+
|
|
39
|
+
expect(twice).toBe(once);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("can split injected prompt from body", () => {
|
|
43
|
+
const injected = appendCronHiddenPrompt("set a reminder every day at 9am");
|
|
44
|
+
const result = splitCronHiddenPrompt(injected);
|
|
45
|
+
|
|
46
|
+
expect(result.base).toBe("set a reminder every day at 9am");
|
|
47
|
+
expect(result.prompt).toBeDefined();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("applies to context command body only when needed", () => {
|
|
51
|
+
const ctx: { Body?: string; CommandBody?: string } = { Body: "每天 18:00 提醒我下班喝水" };
|
|
52
|
+
const changed = applyCronHiddenPromptToContext(ctx);
|
|
53
|
+
|
|
54
|
+
expect(changed).toBe(true);
|
|
55
|
+
expect(ctx.CommandBody).toContain("delivery.mode=\"announce\"");
|
|
56
|
+
});
|
|
57
|
+
});
|
package/src/cron/index.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
const CRON_HIDDEN_PROMPT = `
|
|
2
|
-
When creating or updating a cron task,
|
|
3
|
-
- Do not
|
|
4
|
-
- sessionTarget="isolated"
|
|
5
|
-
- payload.kind="agentTurn"
|
|
6
|
-
- payload.
|
|
7
|
-
-
|
|
1
|
+
const CRON_HIDDEN_PROMPT = `
|
|
2
|
+
When creating or updating a cron task, always store a fixed delivery target in the job itself.
|
|
3
|
+
- Use the built-in cron tool (action=add/update). Do not run shell commands.
|
|
4
|
+
- Must use sessionTarget="isolated" for reminder jobs.
|
|
5
|
+
- payload.kind="agentTurn"
|
|
6
|
+
- payload.message must be plain user-visible reminder text only.
|
|
7
|
+
- You must encode runtime guardrails directly into payload.message so the cron run can follow them without extra context.
|
|
8
|
+
- Runtime guardrails to encode in payload.message:
|
|
9
|
+
- return plain text only
|
|
10
|
+
- never call any tool
|
|
11
|
+
- never call the message tool
|
|
12
|
+
- never send manually; delivery is handled by cron delivery settings
|
|
13
|
+
- Do not include tool directives, "NO_REPLY", or heartbeat markers in payload.message.
|
|
14
|
+
- Job name is never a message target.
|
|
15
|
+
- During cron run, must return plain text only and never call the message tool.
|
|
16
|
+
- Use top-level delivery with announce mode:
|
|
17
|
+
delivery.mode="announce"
|
|
18
|
+
delivery.channel=<OriginatingChannel> (example: "qqbot")
|
|
19
|
+
delivery.to=<OriginatingTo> (examples: "user:<openid>" / "group:<group_openid>")
|
|
20
|
+
delivery.accountId=<AccountId> when available
|
|
21
|
+
- Never set delivery.channel="last" for multi-channel environments.
|
|
22
|
+
- If OriginatingChannel/OriginatingTo are unavailable, ask a concise follow-up for channel and target.
|
|
8
23
|
- Do not call the message tool to send`;
|
|
9
24
|
|
|
10
25
|
const CRON_TRIGGER_KEYWORDS = [
|