@@ -195,6 +195,40 @@ describe('executeChannelBridgeTick', () => {
195195 ] ) ;
196196 } ) ;
197197
198+ it ( 'includes previous session id when /attach replaces an existing binding' , async ( ) => {
199+ const store = createInMemoryChannelBindingStore ( ) ;
200+ const harness = createAdapterHarness ( ) ;
201+
202+ await store . upsertBinding ( {
203+ providerId : 'telegram' ,
204+ conversationId : '-1001' ,
205+ threadId : '88' ,
206+ sessionId : 'sess-old' ,
207+ lastForwardedSeq : 12 ,
208+ } ) ;
209+
210+ const { deps } = createDepsHarness ( {
211+ resolveSessionIdOrPrefix : async ( ) => ( { ok : true as const , sessionId : 'sess-new' } ) ,
212+ resolveLatestSessionSeq : async ( ) => 41 ,
213+ } ) ;
214+
215+ harness . pushInbound ( {
216+ providerId : 'telegram' ,
217+ conversationId : '-1001' ,
218+ threadId : '88' ,
219+ text : '/attach sess-new' ,
220+ messageId : 'm-attach-replace' ,
221+ } ) ;
222+
223+ await executeChannelBridgeTick ( {
224+ store,
225+ adapters : [ harness . adapter ] ,
226+ deps,
227+ } ) ;
228+
229+ expect ( harness . sent . some ( ( row ) => row . text . includes ( 'replaced previous session sess-old' ) ) ) . toBe ( true ) ;
230+ } ) ;
231+
198232 it ( 'supports /sessions and /detach command flow' , async ( ) => {
199233 const store = createInMemoryChannelBindingStore ( ) ;
200234 const harness = createAdapterHarness ( ) ;
@@ -500,6 +534,44 @@ describe('executeChannelBridgeTick', () => {
500534 expect ( binding ?. lastForwardedSeq ) . toBe ( 10 ) ;
501535 expect ( warnings . some ( ( row ) => row . message . includes ( 'Failed to forward agent output to channel' ) ) ) . toBe ( true ) ;
502536 } ) ;
537+
538+ it ( 'deduplicates repeated inbound messages across direct executeChannelBridgeTick calls' , async ( ) => {
539+ const store = createInMemoryChannelBindingStore ( ) ;
540+ const harness = createAdapterHarness ( ) ;
541+
542+ await store . upsertBinding ( {
543+ providerId : 'telegram' ,
544+ conversationId : 'direct-dedupe-room' ,
545+ threadId : null ,
546+ sessionId : 'sess-direct-dedupe' ,
547+ lastForwardedSeq : 0 ,
548+ } ) ;
549+
550+ const { deps, sentToSession } = createDepsHarness ( ) ;
551+ const repeated = {
552+ providerId : 'telegram' as const ,
553+ conversationId : 'direct-dedupe-room' ,
554+ threadId : null ,
555+ text : 'same payload' ,
556+ messageId : 'direct-dedupe-id-1' ,
557+ } ;
558+
559+ harness . pushInbound ( repeated ) ;
560+ await executeChannelBridgeTick ( {
561+ store,
562+ adapters : [ harness . adapter ] ,
563+ deps,
564+ } ) ;
565+
566+ harness . pushInbound ( repeated ) ;
567+ await executeChannelBridgeTick ( {
568+ store,
569+ adapters : [ harness . adapter ] ,
570+ deps,
571+ } ) ;
572+
573+ expect ( sentToSession ) . toHaveLength ( 1 ) ;
574+ } ) ;
503575} ) ;
504576
505577describe ( 'startChannelBridgeWorker' , ( ) => {
0 commit comments