From 15b39313cc128be0de33bbfeead34e092bd01050 Mon Sep 17 00:00:00 2001 From: Chencheng Li <49442600+chencheng-li@users.noreply.github.com> Date: Fri, 8 May 2026 04:19:28 -0700 Subject: [PATCH] fix: separate Current time from Reference UTC (#42654) Merged via squash. Prepared head SHA: 0829399ebd1837c84a46fb84db80dd7f4b8bba30 Co-authored-by: chencheng-li <49442600+chencheng-li@users.noreply.github.com> Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com> Reviewed-by: @altaywtf --- CHANGELOG.md | 1 + extensions/memory-core/index.test.ts | 3 ++- extensions/memory-core/src/dreaming.test.ts | 3 ++- src/agents/current-time.ts | 2 +- src/auto-reply/reply/post-compaction-context.test.ts | 5 ++--- src/auto-reply/reply/session-reset-prompt.test.ts | 5 ++--- src/cron/isolated-agent.session-identity.test.ts | 3 ++- test/helpers/agents/prompt-composition-scenarios.ts | 6 ++++-- 8 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33649519ae2..ea6be581312 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -642,6 +642,7 @@ Docs: https://docs.openclaw.ai - Gateway/nodes: preserve the live node registry session and invoke ownership when an older same-node WebSocket closes after reconnecting. (#78351) Thanks @samzong. - Browser/downloads: route explicit and managed browser download output directories through `fs-safe` validation before staging final files, so symlinked output roots are rejected before writes. (#78780) Thanks @jesse-merhi. - Agents/PI: skip the idle wait during aborted embedded-run cleanup, so stopped or timed-out runs clear pending tool state and release the session lock promptly. (#74919) Thanks @medns. +- Agents/current-time: split UTC into a separate `Reference UTC:` prompt line so local `Current time:` stays anchored to the user's timezone. (#42654) Thanks @chencheng-li. ## 2026.5.3-1 diff --git a/extensions/memory-core/index.test.ts b/extensions/memory-core/index.test.ts index 4bfc4955f88..90363bd7f14 100644 --- a/extensions/memory-core/index.test.ts +++ b/extensions/memory-core/index.test.ts @@ -84,8 +84,9 @@ describe("buildMemoryFlushPlan", () => { expect(plan?.prompt).toContain("memory/2026-02-16.md"); expect(plan?.prompt).toContain( - "Current time: Monday, February 16th, 2026 - 10:00 AM (America/New_York) / 2026-02-16 15:00 UTC", + "Current time: Monday, February 16th, 2026 - 10:00 AM (America/New_York)", ); + expect(plan?.prompt).toContain("Reference UTC: 2026-02-16 15:00 UTC"); expect(plan?.relativePath).toBe("memory/2026-02-16.md"); }); diff --git a/extensions/memory-core/src/dreaming.test.ts b/extensions/memory-core/src/dreaming.test.ts index b53bd7a493e..d28e0b498be 100644 --- a/extensions/memory-core/src/dreaming.test.ts +++ b/extensions/memory-core/src/dreaming.test.ts @@ -1943,7 +1943,8 @@ describe("short-term dreaming trigger", () => { const result = await runShortTermDreamingPromotionIfTriggered({ cleanedBody: [ "[cron:e795558c-a273-4124-ba88-d4916688d977 Memory Dreaming Promotion] __openclaw_memory_core_short_term_promotion_dream__", - "Current time: Thursday, April 16th, 2026 - 3:10 PM (America/Los_Angeles) / 2026-04-16 22:10 UTC", + "Current time: Thursday, April 16th, 2026 - 3:10 PM (America/Los_Angeles)", + "Reference UTC: 2026-04-16 22:10 UTC", ].join("\n"), trigger: "cron", workspaceDir, diff --git a/src/agents/current-time.ts b/src/agents/current-time.ts index b98b8594669..f0de821e226 100644 --- a/src/agents/current-time.ts +++ b/src/agents/current-time.ts @@ -26,7 +26,7 @@ export function resolveCronStyleNow(cfg: TimeConfigLike, nowMs: number): CronSty const formattedTime = formatUserTime(new Date(nowMs), userTimezone, userTimeFormat) ?? new Date(nowMs).toISOString(); const utcTime = new Date(nowMs).toISOString().replace("T", " ").slice(0, 16) + " UTC"; - const timeLine = `Current time: ${formattedTime} (${userTimezone}) / ${utcTime}`; + const timeLine = `Current time: ${formattedTime} (${userTimezone})\nReference UTC: ${utcTime}`; return { userTimezone, formattedTime, timeLine }; } diff --git a/src/auto-reply/reply/post-compaction-context.test.ts b/src/auto-reply/reply/post-compaction-context.test.ts index 981304c4a90..ba2e86b2942 100644 --- a/src/auto-reply/reply/post-compaction-context.test.ts +++ b/src/auto-reply/reply/post-compaction-context.test.ts @@ -262,9 +262,8 @@ Never modify memory/YYYY-MM-DD.md destructively. expect(result).not.toBeNull(); expect(result).toContain("memory/2026-03-03.md"); expect(result).not.toContain("memory/YYYY-MM-DD.md"); - expect(result).toContain( - "Current time: Tuesday, March 3rd, 2026 - 9:00 AM (America/New_York) / 2026-03-03 14:00 UTC", - ); + expect(result).toContain("Current time: Tuesday, March 3rd, 2026 - 9:00 AM (America/New_York)"); + expect(result).toContain("Reference UTC: 2026-03-03 14:00 UTC"); }); it("appends current time line even when no YYYY-MM-DD placeholder is present", async () => { diff --git a/src/auto-reply/reply/session-reset-prompt.test.ts b/src/auto-reply/reply/session-reset-prompt.test.ts index d4f18acf6f4..1e8aa20280d 100644 --- a/src/auto-reply/reply/session-reset-prompt.test.ts +++ b/src/auto-reply/reply/session-reset-prompt.test.ts @@ -50,9 +50,8 @@ describe("buildBareSessionResetPrompt", () => { // 2026-03-03 14:00 UTC = 2026-03-03 09:00 EST const nowMs = Date.UTC(2026, 2, 3, 14, 0, 0); const prompt = buildBareSessionResetPrompt(cfg, nowMs); - expect(prompt).toContain( - "Current time: Tuesday, March 3rd, 2026 - 9:00 AM (America/New_York) / 2026-03-03 14:00 UTC", - ); + expect(prompt).toContain("Current time: Tuesday, March 3rd, 2026 - 9:00 AM (America/New_York)"); + expect(prompt).toContain("Reference UTC: 2026-03-03 14:00 UTC"); }); it("does not append a duplicate current time line", () => { diff --git a/src/cron/isolated-agent.session-identity.test.ts b/src/cron/isolated-agent.session-identity.test.ts index 9bd543d7d60..dd3b7e00650 100644 --- a/src/cron/isolated-agent.session-identity.test.ts +++ b/src/cron/isolated-agent.session-identity.test.ts @@ -55,7 +55,8 @@ describe("runCronIsolatedAgentTurn session identity", () => { const lines = call?.prompt?.split("\n") ?? []; expect(lines[0]).toContain("[cron:job-1"); expect(lines[0]).toContain("do it"); - expect(lines[1]).toMatch(/^Current time: .+ \(.+\) \/ \d{4}-\d{2}-\d{2} \d{2}:\d{2} UTC$/); + expect(lines[1]).toMatch(/^Current time: .+ \(.+\)$/); + expect(lines[2]).toMatch(/^Reference UTC: \d{4}-\d{2}-\d{2} \d{2}:\d{2} UTC$/); }); }); diff --git a/test/helpers/agents/prompt-composition-scenarios.ts b/test/helpers/agents/prompt-composition-scenarios.ts index f7d5d403f25..4043dd51d41 100644 --- a/test/helpers/agents/prompt-composition-scenarios.ts +++ b/test/helpers/agents/prompt-composition-scenarios.ts @@ -594,7 +594,8 @@ async function createMaintenanceScenario(workspaceDir: string): Promise