diff --git a/packages/api/src/activities/activity.spec.ts b/packages/api/src/activities/activity.spec.ts index caed9a532..0e9cb90ad 100644 --- a/packages/api/src/activities/activity.spec.ts +++ b/packages/api/src/activities/activity.spec.ts @@ -35,8 +35,8 @@ describe('Activity', () => { }) .withRecipient(bot) .withServiceUrl('http://localhost') - .withTimestamp(new Date()) - .withLocalTimestamp(new Date()); + .withTimestamp(new Date('2026-06-04T21:00:00.000Z')) + .withLocalTimestamp('2026-06-04T14:00:00.000-07:00'); expect(activity.id).toEqual('1'); expect(activity.type).toEqual('test'); @@ -52,8 +52,22 @@ describe('Activity', () => { expect(activity.recipient).toEqual(bot); expect(activity.serviceUrl).toEqual('http://localhost'); - expect(activity.timestamp).toBeDefined(); - expect(activity.localTimestamp).toBeDefined(); + expect(activity.timestamp).toEqual('2026-06-04T21:00:00.000Z'); + expect(activity.localTimestamp).toEqual('2026-06-04T14:00:00.000-07:00'); + }); + + it('should preserve timestamp strings from constructor data', () => { + const timestamp = '2026-06-04T21:00:00.000Z'; + const localTimestamp = '2026-06-04T14:00:00.000-07:00'; + + const activity = new Activity({ + type: 'test', + timestamp, + localTimestamp, + }); + + expect(activity.timestamp).toEqual(timestamp); + expect(activity.localTimestamp).toEqual(localTimestamp); }); it('should build from interface', () => { diff --git a/packages/api/src/activities/activity.ts b/packages/api/src/activities/activity.ts index 974d281e2..eafb782c6 100644 --- a/packages/api/src/activities/activity.ts +++ b/packages/api/src/activities/activity.ts @@ -34,7 +34,7 @@ export interface IActivity { /** * Contains the date and time that the message was sent, in UTC, expressed in ISO-8601 format. */ - timestamp?: Date; + timestamp?: string; /** * A locale name for the contents of the text field. @@ -50,7 +50,7 @@ export interface IActivity { * * For example, 2016-09-23T13:07:49.4714686-07:00. */ - localTimestamp?: Date; + localTimestamp?: string; /** * Contains an ID that uniquely identifies the channel. Set by the channel. @@ -460,7 +460,7 @@ export class Activity implements IActivity { /** * Contains the date and time that the message was sent, in UTC, expressed in ISO-8601 format. */ - timestamp?: Date; + timestamp?: string; /** * A locale name for the contents of the text field. @@ -476,7 +476,7 @@ export class Activity implements IActivity { * * For example, 2016-09-23T13:07:49.4714686-07:00. */ - localTimestamp?: Date; + localTimestamp?: string; /** * Contains an ID that uniquely identifies the channel. Set by the channel. @@ -626,8 +626,13 @@ export class Activity implements IActivity { return this; } - withTimestamp(value: Date) { - this.timestamp = value; + /** + * Sets the activity timestamp as an ISO-8601 string. + * + * @deprecated Use ActivityInput/MessageActivityInput/TypingActivityInput when constructing outbound activities. + */ + withTimestamp(value: Date | string) { + this.timestamp = value instanceof Date ? value.toISOString() : value; return this; } @@ -636,8 +641,13 @@ export class Activity implements IActivity { return this; } - withLocalTimestamp(value: Date) { - this.localTimestamp = value; + /** + * Sets the activity's local timestamp as an ISO-8601 string. + * + * @deprecated Use ActivityInput/MessageActivityInput/TypingActivityInput when constructing outbound activities. + */ + withLocalTimestamp(value: Date | string) { + this.localTimestamp = value instanceof Date ? value.toISOString() : value; return this; } diff --git a/packages/api/src/activities/event/agent-lifecycle.spec.ts b/packages/api/src/activities/event/agent-lifecycle.spec.ts index bad16a679..5c325603b 100644 --- a/packages/api/src/activities/event/agent-lifecycle.spec.ts +++ b/packages/api/src/activities/event/agent-lifecycle.spec.ts @@ -15,7 +15,7 @@ const BLUEPRINT_ID = '00000000-0000-0000-0000-000000000005'; const baseActivity = { type: 'event', id: 'activity-id', - timestamp: new Date('2026-06-29T00:00:00Z'), + timestamp: '2026-06-29T00:00:00Z', serviceUrl: 'https://smba.trafficmanager.net/amer/tenant/', channelId: 'agents', from: { id: 'system', name: 'System', role: 'bot', tenantId: TENANT_ID }, diff --git a/packages/devtools/src/stores/ChatStore.ts b/packages/devtools/src/stores/ChatStore.ts index 1809bc46b..d36dcfbe7 100644 --- a/packages/devtools/src/stores/ChatStore.ts +++ b/packages/devtools/src/stores/ChatStore.ts @@ -40,6 +40,10 @@ interface MessageBase { createdDateTime: string; } +const toUTCString = (value?: string | Date) => { + return (value instanceof Date ? value : new Date(value || Date.now())).toUTCString(); +}; + const createMessageBase = ( event: ActivityEvent ): MessageBase => { @@ -66,7 +70,7 @@ const createMessageBase = ( } : undefined, }, - createdDateTime: (event.body.timestamp || new Date()).toUTCString(), + createdDateTime: toUTCString(event.body.timestamp), }; }; @@ -303,7 +307,7 @@ export const useChatStore = create()( message.body.textContent = event.body.text; } - message.lastModifiedDateTime = (event.body.timestamp || new Date()).toUTCString(); + message.lastModifiedDateTime = toUTCString(event.body.timestamp); state.put(state.chat.id, message); return state; },