@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw-china/shared",
3
- "version": "2026.3.4-2",
3
+ "version": "2026.3.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
@@ -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, use the main session's last route as the delivery target.
3
- - Do not ask the user for userId/chatId
4
- - sessionTarget="isolated"
5
- - payload.kind="agentTurn"
6
- - payload.deliver=true
7
- - Do not set payload.channel/to (fall back to last route automatically)
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 = [