@@ -5,11 +5,18 @@ import {
55 HEADER_SESSION_ID ,
66 JSON_MIME_TYPE ,
77} from "./protocol.js" ;
8+ import { PROTOCOL_VERSION } from "./schema/index.js" ;
89import { parseSseStream } from "./sse.js" ;
910import { TestAgent } from "./test-support/test-agent.js" ;
1011import { startTestServer } from "./test-support/test-http-server.js" ;
1112
12- import type { AgentSideConnection } from "./acp.js" ;
13+ import type {
14+ AgentSideConnection ,
15+ InitializeRequest ,
16+ InitializeResponse ,
17+ LoadSessionRequest ,
18+ LoadSessionResponse ,
19+ } from "./acp.js" ;
1320import type { AnyMessage } from "./jsonrpc.js" ;
1421
1522const initializeRequest = {
@@ -57,6 +64,49 @@ function createForkRequest(id: number, sessionId: string) {
5764 } ;
5865}
5966
67+ function createLoadSessionRequest ( id : number , sessionId : string ) {
68+ return {
69+ jsonrpc : "2.0" ,
70+ id,
71+ method : "session/load" ,
72+ params : {
73+ cwd : "/tmp" ,
74+ mcpServers : [ ] ,
75+ sessionId,
76+ } ,
77+ } ;
78+ }
79+
80+ class LoadSessionAgent extends TestAgent {
81+ constructor ( private readonly agentConnection : AgentSideConnection ) {
82+ super ( agentConnection ) ;
83+ }
84+
85+ initialize ( _params : InitializeRequest ) : Promise < InitializeResponse > {
86+ return Promise . resolve ( {
87+ protocolVersion : PROTOCOL_VERSION ,
88+ agentCapabilities : {
89+ loadSession : true ,
90+ } ,
91+ } ) ;
92+ }
93+
94+ async loadSession ( params : LoadSessionRequest ) : Promise < LoadSessionResponse > {
95+ await this . agentConnection . sessionUpdate ( {
96+ sessionId : params . sessionId ,
97+ update : {
98+ sessionUpdate : "agent_message_chunk" ,
99+ content : {
100+ type : "text" ,
101+ text : "replayed-session-history" ,
102+ } ,
103+ } ,
104+ } ) ;
105+
106+ return { } ;
107+ }
108+ }
109+
60110describe ( "AcpServer session SSE" , ( ) => {
61111 it ( "streams prompt updates and responses on the session SSE stream" , async ( ) => {
62112 const server = await startTestServer (
@@ -203,6 +253,58 @@ describe("AcpServer session SSE", () => {
203253 }
204254 } ) ;
205255
256+ it ( "routes session/load replay updates to session SSE and final response to connection SSE" , async ( ) => {
257+ const server = await startTestServer (
258+ ( conn : AgentSideConnection ) => new LoadSessionAgent ( conn ) ,
259+ ) ;
260+
261+ try {
262+ const connectionId = await initialize ( server . url ) ;
263+ const sessionId = "existing-session" ;
264+ const connectionSse = await openConnectionSse ( server . url , connectionId ) ;
265+ const sessionSse = await openSessionSse (
266+ server . url ,
267+ connectionId ,
268+ sessionId ,
269+ ) ;
270+ const accepted = await postJson (
271+ server . url ,
272+ createLoadSessionRequest ( 3 , sessionId ) ,
273+ {
274+ [ HEADER_CONNECTION_ID ] : connectionId ,
275+ [ HEADER_SESSION_ID ] : sessionId ,
276+ } ,
277+ ) ;
278+
279+ expect ( sessionSse . status ) . toBe ( 200 ) ;
280+ expect ( accepted . status ) . toBe ( 202 ) ;
281+ expect ( await readSseMessages ( sessionSse , 1 ) ) . toMatchObject ( [
282+ {
283+ jsonrpc : "2.0" ,
284+ method : "session/update" ,
285+ params : {
286+ sessionId,
287+ update : {
288+ sessionUpdate : "agent_message_chunk" ,
289+ content : {
290+ text : "replayed-session-history" ,
291+ } ,
292+ } ,
293+ } ,
294+ } ,
295+ ] ) ;
296+ expect ( await readSseMessages ( connectionSse , 1 ) ) . toMatchObject ( [
297+ {
298+ jsonrpc : "2.0" ,
299+ id : 3 ,
300+ result : { } ,
301+ } ,
302+ ] ) ;
303+ } finally {
304+ await server . close ( ) ;
305+ }
306+ } ) ;
307+
206308 it ( "replays buffered session messages when session SSE attaches after prompt" , async ( ) => {
207309 const server = await startTestServer ( ) ;
208310
0 commit comments