diff --git a/src/auto-reply/envelope.test.ts b/src/auto-reply/envelope.test.ts index ecb35f0dd9..179bd69abb 100644 --- a/src/auto-reply/envelope.test.ts +++ b/src/auto-reply/envelope.test.ts @@ -23,7 +23,7 @@ describe("formatAgentEnvelope", () => { process.env.TZ = originalTz; - expect(body).toBe("[WebChat user1 mac-mini 10.0.0.5 2025-01-02T03:04Z] hello"); + expect(body).toBe("[WebChat user1 mac-mini 10.0.0.5 Thu 2025-01-02T03:04Z] hello"); }); it("formats timestamps in local timezone by default", () => { @@ -39,7 +39,7 @@ describe("formatAgentEnvelope", () => { process.env.TZ = originalTz; - expect(body).toMatch(/\[WebChat 2025-01-01 19:04 [^\]]+\] hello/); + expect(body).toMatch(/\[WebChat Wed 2025-01-01 19:04 [^\]]+\] hello/); }); it("formats timestamps in UTC when configured", () => { @@ -56,7 +56,7 @@ describe("formatAgentEnvelope", () => { process.env.TZ = originalTz; - expect(body).toBe("[WebChat 2025-01-02T03:04Z] hello"); + expect(body).toBe("[WebChat Thu 2025-01-02T03:04Z] hello"); }); it("formats timestamps in user timezone when configured", () => { @@ -68,7 +68,7 @@ describe("formatAgentEnvelope", () => { body: "hello", }); - expect(body).toMatch(/\[WebChat 2025-01-02 04:04 [^\]]+\] hello/); + expect(body).toMatch(/\[WebChat Thu 2025-01-02 04:04 [^\]]+\] hello/); }); it("omits timestamps when configured", () => { diff --git a/src/auto-reply/envelope.ts b/src/auto-reply/envelope.ts index af10b15ef1..6e01048139 100644 --- a/src/auto-reply/envelope.ts +++ b/src/auto-reply/envelope.ts @@ -107,13 +107,35 @@ function formatTimestamp( return undefined; } const zone = resolveEnvelopeTimezone(resolved); - if (zone.mode === "utc") { - return formatUtcTimestamp(date); + // Include a weekday prefix so models do not need to derive DOW from the date + // (small models are notoriously unreliable at that). + const weekday = (() => { + try { + if (zone.mode === "utc") { + return new Intl.DateTimeFormat("en-US", { timeZone: "UTC", weekday: "short" }).format(date); + } + if (zone.mode === "local") { + return new Intl.DateTimeFormat("en-US", { weekday: "short" }).format(date); + } + return new Intl.DateTimeFormat("en-US", { timeZone: zone.timeZone, weekday: "short" }).format( + date, + ); + } catch { + return undefined; + } + })(); + + const formatted = + zone.mode === "utc" + ? formatUtcTimestamp(date) + : zone.mode === "local" + ? formatZonedTimestamp(date) + : formatZonedTimestamp(date, { timeZone: zone.timeZone }); + + if (!formatted) { + return undefined; } - if (zone.mode === "local") { - return formatZonedTimestamp(date); - } - return formatZonedTimestamp(date, { timeZone: zone.timeZone }); + return weekday ? `${weekday} ${formatted}` : formatted; } export function formatAgentEnvelope(params: AgentEnvelopeParams): string { diff --git a/test/helpers/envelope-timestamp.ts b/test/helpers/envelope-timestamp.ts index aa63d612d9..22aa3580d1 100644 --- a/test/helpers/envelope-timestamp.ts +++ b/test/helpers/envelope-timestamp.ts @@ -7,13 +7,30 @@ type EnvelopeTimestampZone = string; export function formatEnvelopeTimestamp(date: Date, zone: EnvelopeTimestampZone = "utc"): string { const normalized = zone.trim().toLowerCase(); + const weekday = (() => { + try { + if (normalized === "utc" || normalized === "gmt") { + return new Intl.DateTimeFormat("en-US", { timeZone: "UTC", weekday: "short" }).format(date); + } + if (normalized === "local" || normalized === "host") { + return new Intl.DateTimeFormat("en-US", { weekday: "short" }).format(date); + } + return new Intl.DateTimeFormat("en-US", { timeZone: zone, weekday: "short" }).format(date); + } catch { + return undefined; + } + })(); + if (normalized === "utc" || normalized === "gmt") { - return formatUtcTimestamp(date); + const ts = formatUtcTimestamp(date); + return weekday ? `${weekday} ${ts}` : ts; } if (normalized === "local" || normalized === "host") { - return formatZonedTimestamp(date) ?? formatUtcTimestamp(date); + const ts = formatZonedTimestamp(date) ?? formatUtcTimestamp(date); + return weekday ? `${weekday} ${ts}` : ts; } - return formatZonedTimestamp(date, { timeZone: zone }) ?? formatUtcTimestamp(date); + const ts = formatZonedTimestamp(date, { timeZone: zone }) ?? formatUtcTimestamp(date); + return weekday ? `${weekday} ${ts}` : ts; } export function formatLocalEnvelopeTimestamp(date: Date): string {