feat(auto-reply): make agent time-aware with message timestamps

Add human-readable timestamp field to the Conversation info JSON block.

Before:
  {
    "conversation_label": "D id:123"
  }

After:
  {
    "conversation_label": "D id:123",
    "timestamp": "Sun 2026-02-15 13:35 GMT+8"
  }

Benefits:
- Better time awareness for time-related questions
- Understand conversation gaps and response delays
- Handle delayed message delivery
- Context for relative time references ("just now", "later")
This commit is contained in:
Liu Yuan
2026-02-15 13:38:28 +08:00
committed by Shakker
parent 10481097f8
commit c596658b8d

View File

@@ -1,5 +1,6 @@
import { normalizeChatType } from "../../channels/chat-type.js";
import { resolveSenderLabel } from "../../channels/sender-label.js";
import { formatZonedTimestamp } from "../../infra/format-time/format-datetime.js";
import type { TemplateContext } from "../templating.js";
function safeTrim(value: unknown): string | undefined {
@@ -10,6 +11,26 @@ function safeTrim(value: unknown): string | undefined {
return trimmed ? trimmed : undefined;
}
function formatConversationTimestamp(value: unknown): string | undefined {
if (typeof value !== "number" || !Number.isFinite(value)) {
return undefined;
}
const date = new Date(value);
if (Number.isNaN(date.getTime())) {
return undefined;
}
const formatted = formatZonedTimestamp(date);
if (!formatted) {
return undefined;
}
try {
const weekday = new Intl.DateTimeFormat("en-US", { weekday: "short" }).format(date);
return weekday ? `${weekday} ${formatted}` : formatted;
} catch {
return formatted;
}
}
export function buildInboundMetaSystemPrompt(ctx: TemplateContext): string {
const chatType = normalizeChatType(ctx.ChatType);
const isDirect = !chatType || chatType === "direct";
@@ -66,6 +87,8 @@ export function buildInboundUserContextPrefix(ctx: TemplateContext): string {
const messageId = safeTrim(ctx.MessageSid);
const messageIdFull = safeTrim(ctx.MessageSidFull);
const timestampStr = formatConversationTimestamp(ctx.Timestamp);
const conversationInfo = {
message_id: isDirect ? undefined : messageId,
message_id_full: isDirect
@@ -79,6 +102,7 @@ export function buildInboundUserContextPrefix(ctx: TemplateContext): string {
sender: isDirect
? undefined
: (safeTrim(ctx.SenderE164) ?? safeTrim(ctx.SenderId) ?? safeTrim(ctx.SenderUsername)),
timestamp: timestampStr,
group_subject: safeTrim(ctx.GroupSubject),
group_channel: safeTrim(ctx.GroupChannel),
group_space: safeTrim(ctx.GroupSpace),