diff --git a/CHANGELOG.md b/CHANGELOG.md index c58162ad9f5..d51f5383c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Docs: https://docs.openclaw.ai - Telegram/direct sessions: keep commentary-only assistant fallback payloads out of visible direct delivery, so Codex planning chatter cannot leak into Telegram DMs when a run has no `final_answer` text. (#65112) Thanks @vincentkoc. - Infra/net: fix multipart FormData fields (including `model`) being silently dropped when a guarded runtime fetch body crosses a FormData implementation boundary, restoring OpenAI audio transcription requests that failed with HTTP 400. (#64349) Thanks @petr-sloup. - Dreaming/diary: use the host local timezone for diary timestamps when `dreaming.timezone` is unset, so `DREAMS.md` and the UI stop defaulting to UTC. (#65034) Thanks @neo1027144-creator and @vincentkoc. +- Dreaming/diary: include the timezone abbreviation in diary timestamps so `DREAMS.md` and the UI make UTC or local host time explicit. (#65057) Thanks @Yanhu007 and @vincentkoc. - Plugins/memory: restore cached memory capability public artifacts on plugin-registry cache hits so memory-backed artifact surfaces stay visible after warm loads. Thanks @sercada and @vincentkoc. - Gateway/cron: preserve requested isolated-agent config across runtime reloads so subagent jobs and heartbeat overrides keep the right workspace and heartbeat settings when the hot-loaded snapshot is stale. Thanks @l0cka and @vincentkoc. - Gateway/plugins: always send a non-empty `idempotencyKey` for plugin subagent runs, so dreaming narrative jobs stop failing gateway schema validation. (#65354) Thanks @CodeForgeNet and @vincentkoc. diff --git a/extensions/memory-core/src/dreaming-narrative.test.ts b/extensions/memory-core/src/dreaming-narrative.test.ts index 8e3ed5daa1b..f9627f11c4c 100644 --- a/extensions/memory-core/src/dreaming-narrative.test.ts +++ b/extensions/memory-core/src/dreaming-narrative.test.ts @@ -121,6 +121,7 @@ describe("formatNarrativeDate", () => { expect(date).toContain("April"); expect(date).toContain("2026"); expect(date).toContain("3:00"); + expect(date).toContain("UTC"); }); it("applies an explicit timezone", () => { @@ -131,6 +132,7 @@ describe("formatNarrativeDate", () => { ); expect(date).toContain("2:46"); expect(date).toContain("PM"); + expect(date).toContain("PDT"); }); it("uses host local timezone when timezone is undefined (#65027)", () => { @@ -144,6 +146,7 @@ describe("formatNarrativeDate", () => { // 21:46 UTC → 14:46 PDT → "2:46 PM" expect(result).toContain("2:46"); expect(result).toContain("PM"); + expect(result).toContain("PDT"); } finally { if (originalTZ === undefined) { delete process.env.TZ; diff --git a/extensions/memory-core/src/dreaming-narrative.ts b/extensions/memory-core/src/dreaming-narrative.ts index 5314b794714..54032d1f410 100644 --- a/extensions/memory-core/src/dreaming-narrative.ts +++ b/extensions/memory-core/src/dreaming-narrative.ts @@ -238,6 +238,11 @@ export function formatNarrativeDate(epochMs: number, timezone?: string): string hour: "numeric", minute: "2-digit", hour12: true, + // Always include the timezone abbreviation so the reader knows which + // timezone the timestamp refers to. Without this, users who haven't + // configured a timezone see bare times that look local but are actually + // UTC, causing confusion (see #65027). + timeZoneName: "short", }; return new Intl.DateTimeFormat("en-US", opts).format(new Date(epochMs)); }