Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions backend/__tests__/utils/formatRelativeTime.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { formatRelativeTime } = require('../../utils/formatRelativeTime');

describe('formatRelativeTime', () => {
const now = new Date('2026-06-26T12:00:00.000Z');

beforeAll(() => {
jest.useFakeTimers();
jest.setSystemTime(now);
});

afterAll(() => {
jest.useRealTimers();
});

it('returns minutes and hours for recent dates', () => {
expect(formatRelativeTime(new Date('2026-06-26T11:58:00.000Z'))).toBe('2m');
expect(formatRelativeTime(new Date('2026-06-26T09:00:00.000Z'))).toBe('3h');
});

it('returns Yesterday for the prior day', () => {
expect(formatRelativeTime(new Date('2026-06-25T18:00:00.000Z'))).toBe('Yesterday');
});
});
2 changes: 1 addition & 1 deletion backend/services/agentMessageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ class AgentMessageService {
// nearby AND no `[[upload:` directive in the body.
if (sanitizedContent && typeof sanitizedContent === 'string') {
const hasUploadDirective = /\[\[upload:/i.test(sanitizedContent);
const claimsAttachment = /\b(?:i(?:'ve| have)?|done\s*[—-]?\s*i|i\s+just|just\s+attached|i\s+already)\s+(?:attached|uploaded|posted)\b[^.\n]{0,80}\b(?:file|deck|attachment|pptx|docx|xlsx|pdf|csv|image|artifact)\b/i.test(sanitizedContent);
const claimsAttachment = /(?:\b(?:i(?:'ve| have)?|done\s*[—-]?\s*i|i\s+just|just\s+attached|i\s+already)\s+(?:attached|uploaded|posted)\b|\b(?:attached|uploaded|posted)\s+(?:the|a|an)\b)(?=[^.\n]{0,80}\b(?:file|deck|attachment|pptx|docx|xlsx|pdf|csv|image|artifact)\b)(?![^.\n]{0,40}\b(?:pixel|nova|aria|ops|cody|theo|sam)\b[^.\n]{0,20}\b(?:attached|uploaded|posted)\b)/i.test(sanitizedContent);
if (claimsAttachment && !hasUploadDirective) {
sanitizedContent += '\n\n⚠️ _(system note: this message claims an attachment but no `[[upload:...]]` directive is in the body. The agent may not have actually called `commonly_attach_file`. Check the agent\'s workspace for the file and re-attach if needed.)_';
console.warn(`[agent-msg] false-attach-claim from agent=${agentName} instance=${instanceId} pod=${podId} — appended system note`);
Expand Down
25 changes: 25 additions & 0 deletions backend/utils/formatRelativeTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const MINUTE_MS = 60 * 1000;
const HOUR_MS = 60 * MINUTE_MS;
const DAY_MS = 24 * HOUR_MS;

export function formatRelativeTime(date: Date): string {
const diffMs = Date.now() - date.getTime();
const absDiffMs = Math.abs(diffMs);

if (absDiffMs < MINUTE_MS) return 'Just now';
if (absDiffMs < HOUR_MS) return `${Math.round(absDiffMs / MINUTE_MS)}m`;
if (absDiffMs < DAY_MS) return `${Math.round(absDiffMs / HOUR_MS)}h`;

const now = new Date();
const input = new Date(date);
const isYesterday =
now.getFullYear() === input.getFullYear() &&
now.getMonth() === input.getMonth() &&
now.getDate() - input.getDate() === 1;

if (isYesterday) return 'Yesterday';

return `${Math.round(absDiffMs / DAY_MS)}d`;
}

export default formatRelativeTime;