@@ -538,6 +538,126 @@ describe("Connection", () => {
538538 expect ( response . authMethods ?. [ 0 ] . id ) . toBe ( "oauth" ) ;
539539 } ) ;
540540
541+ it ( "preserves unknown properties on known incoming params" , async ( ) => {
542+ let receivedInitializeParams : Record < string , unknown > | undefined ;
543+ let receivedSessionUpdate : Record < string , unknown > | undefined ;
544+
545+ class TestClient implements Client {
546+ async writeTextFile (
547+ _ : WriteTextFileRequest ,
548+ ) : Promise < WriteTextFileResponse > {
549+ return { } ;
550+ }
551+ async readTextFile (
552+ _ : ReadTextFileRequest ,
553+ ) : Promise < ReadTextFileResponse > {
554+ return { content : "test" } ;
555+ }
556+ async requestPermission (
557+ _ : RequestPermissionRequest ,
558+ ) : Promise < RequestPermissionResponse > {
559+ return {
560+ outcome : {
561+ outcome : "selected" ,
562+ optionId : "allow" ,
563+ } ,
564+ } ;
565+ }
566+ async sessionUpdate ( params : SessionNotification ) : Promise < void > {
567+ receivedSessionUpdate = params as unknown as Record < string , unknown > ;
568+ }
569+ }
570+
571+ class TestAgent implements Agent {
572+ async initialize ( params : InitializeRequest ) : Promise < InitializeResponse > {
573+ receivedInitializeParams = params as unknown as Record < string , unknown > ;
574+ return {
575+ protocolVersion : PROTOCOL_VERSION ,
576+ agentCapabilities : { loadSession : false } ,
577+ authMethods : [ ] ,
578+ } ;
579+ }
580+ async newSession ( _ : NewSessionRequest ) : Promise < NewSessionResponse > {
581+ return { sessionId : "test-session" } ;
582+ }
583+ async loadSession ( _ : LoadSessionRequest ) : Promise < LoadSessionResponse > {
584+ return { } ;
585+ }
586+ async authenticate ( _ : AuthenticateRequest ) : Promise < void > {
587+ // no-op
588+ }
589+ async prompt ( _ : PromptRequest ) : Promise < PromptResponse > {
590+ return { stopReason : "end_turn" } ;
591+ }
592+ async cancel ( _ : CancelNotification ) : Promise < void > {
593+ // no-op
594+ }
595+ }
596+
597+ const agentConnection = new ClientSideConnection (
598+ ( ) => new TestClient ( ) ,
599+ ndJsonStream ( clientToAgent . writable , agentToClient . readable ) ,
600+ ) ;
601+
602+ const clientConnection = new AgentSideConnection (
603+ ( ) => new TestAgent ( ) ,
604+ ndJsonStream ( agentToClient . writable , clientToAgent . readable ) ,
605+ ) ;
606+
607+ await agentConnection . initialize ( {
608+ protocolVersion : PROTOCOL_VERSION ,
609+ clientCapabilities : {
610+ fs : {
611+ readTextFile : false ,
612+ writeTextFile : false ,
613+ experimentalFs : true ,
614+ } ,
615+ customCapability : {
616+ enabled : true ,
617+ } ,
618+ } ,
619+ extraTopLevel : "keep me" ,
620+ } as any ) ;
621+
622+ await clientConnection . sessionUpdate ( {
623+ sessionId : "test-session" ,
624+ update : {
625+ sessionUpdate : "agent_message_chunk" ,
626+ content : {
627+ type : "text" ,
628+ text : "Hello from agent" ,
629+ } ,
630+ extraUpdateField : {
631+ keep : true ,
632+ } ,
633+ } ,
634+ extraNotificationField : "keep this too" ,
635+ } as any ) ;
636+
637+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
638+
639+ expect ( receivedInitializeParams ) . toMatchObject ( {
640+ extraTopLevel : "keep me" ,
641+ clientCapabilities : {
642+ customCapability : {
643+ enabled : true ,
644+ } ,
645+ fs : {
646+ experimentalFs : true ,
647+ } ,
648+ } ,
649+ } ) ;
650+
651+ expect ( receivedSessionUpdate ) . toMatchObject ( {
652+ extraNotificationField : "keep this too" ,
653+ update : {
654+ extraUpdateField : {
655+ keep : true ,
656+ } ,
657+ } ,
658+ } ) ;
659+ } ) ;
660+
541661 it ( "handles extension methods and notifications" , async ( ) => {
542662 const extensionLog : string [ ] = [ ] ;
543663
0 commit comments