@@ -164,12 +164,12 @@ func TestClientOptionsE2E(t *testing.T) {
164164 EnableConfigDiscovery : copilot .Bool (true ),
165165 EnableOnDemandInstructionDiscovery : copilot .Bool (true ),
166166 IncludeSubAgentStreamingEvents : copilot .Bool (false ),
167+ CustomAgentsLocalOnly : copilot .Bool (false ),
167168 OnPermissionRequest : copilot .PermissionHandler .ApproveAll ,
168169 })
169170 if err != nil {
170171 t .Fatalf ("CreateSession failed: %v" , err )
171172 }
172- t .Cleanup (func () { session .Disconnect () })
173173
174174 updated := readCapture (t , capturePath )
175175 var createReq * capturedRequest
@@ -196,6 +196,107 @@ func TestClientOptionsE2E(t *testing.T) {
196196 if v , ok := params ["includeSubAgentStreamingEvents" ].(bool ); ! ok || v != false {
197197 t .Errorf ("Expected session.create.params.includeSubAgentStreamingEvents=false, got %v" , params ["includeSubAgentStreamingEvents" ])
198198 }
199+ if v , ok := params ["customAgentsLocalOnly" ].(bool ); ! ok || v != false {
200+ t .Errorf ("Expected session.create.params.customAgentsLocalOnly=false, got %v" , params ["customAgentsLocalOnly" ])
201+ }
202+
203+ sessionID := session .SessionID
204+ if err := session .Disconnect (); err != nil {
205+ t .Fatalf ("Disconnect failed: %v" , err )
206+ }
207+ resumed , err := client .ResumeSession (t .Context (), sessionID , & copilot.ResumeSessionConfig {
208+ CustomAgentsLocalOnly : copilot .Bool (false ),
209+ OnPermissionRequest : copilot .PermissionHandler .ApproveAll ,
210+ })
211+ if err != nil {
212+ t .Fatalf ("ResumeSession failed: %v" , err )
213+ }
214+ t .Cleanup (func () { _ = resumed .Disconnect () })
215+
216+ resumedCapture := readCapture (t , capturePath )
217+ for _ , req := range resumedCapture .Requests {
218+ if req .Method != "session.resume" {
219+ continue
220+ }
221+ resumeParams , ok := req .Params .(map [string ]any )
222+ if ! ok {
223+ t .Fatalf ("Expected session.resume params to be an object, got %T" , req .Params )
224+ }
225+ if v , ok := resumeParams ["customAgentsLocalOnly" ].(bool ); ! ok || v != false {
226+ t .Errorf ("Expected session.resume.params.customAgentsLocalOnly=false, got %v" ,
227+ resumeParams ["customAgentsLocalOnly" ])
228+ }
229+ return
230+ }
231+ t .Fatalf ("session.resume request was not captured. Captured requests: %+v" , resumedCapture .Requests )
232+ })
233+
234+ t .Run ("should send empty-mode custom agent locality defaults in initial requests" , func (t * testing.T ) {
235+ ctx := testharness .NewTestContext (t )
236+ cliPath := filepath .Join (ctx .WorkDir , "fake-cli-empty-" + randomHex (t )+ ".js" )
237+ capturePath := filepath .Join (ctx .WorkDir , "fake-cli-empty-capture-" + randomHex (t )+ ".json" )
238+ if err := os .WriteFile (cliPath , []byte (fakeStdioCliScript ), 0644 ); err != nil {
239+ t .Fatalf ("Failed to write fake CLI script: %v" , err )
240+ }
241+
242+ client := ctx .NewClient (func (opts * copilot.ClientOptions ) {
243+ opts .Connection = copilot.StdioConnection {
244+ Path : cliPath ,
245+ Args : []string {"--capture-file" , capturePath },
246+ }
247+ opts .Mode = copilot .ModeEmpty
248+ opts .BaseDirectory = ctx .WorkDir
249+ opts .UseLoggedInUser = copilot .Bool (false )
250+ })
251+ t .Cleanup (func () { client .ForceStop () })
252+
253+ session , err := client .CreateSession (t .Context (), & copilot.SessionConfig {
254+ AvailableTools : []string {"builtin:ask_user" },
255+ OnPermissionRequest : copilot .PermissionHandler .ApproveAll ,
256+ })
257+ if err != nil {
258+ t .Fatalf ("CreateSession failed: %v" , err )
259+ }
260+ sessionID := session .SessionID
261+ if err := session .Disconnect (); err != nil {
262+ t .Fatalf ("Disconnect failed: %v" , err )
263+ }
264+
265+ resumed , err := client .ResumeSession (t .Context (), sessionID , & copilot.ResumeSessionConfig {
266+ AvailableTools : []string {"builtin:ask_user" },
267+ OnPermissionRequest : copilot .PermissionHandler .ApproveAll ,
268+ })
269+ if err != nil {
270+ t .Fatalf ("ResumeSession failed: %v" , err )
271+ }
272+ t .Cleanup (func () { _ = resumed .Disconnect () })
273+
274+ capture := readCapture (t , capturePath )
275+ foundCreate := false
276+ foundResume := false
277+ for _ , req := range capture .Requests {
278+ params , ok := req .Params .(map [string ]any )
279+ if ! ok {
280+ continue
281+ }
282+ switch req .Method {
283+ case "session.create" :
284+ foundCreate = true
285+ if v , ok := params ["customAgentsLocalOnly" ].(bool ); ! ok || ! v {
286+ t .Errorf ("Expected session.create.params.customAgentsLocalOnly=true, got %v" ,
287+ params ["customAgentsLocalOnly" ])
288+ }
289+ case "session.resume" :
290+ foundResume = true
291+ if v , ok := params ["customAgentsLocalOnly" ].(bool ); ! ok || ! v {
292+ t .Errorf ("Expected session.resume.params.customAgentsLocalOnly=true, got %v" ,
293+ params ["customAgentsLocalOnly" ])
294+ }
295+ }
296+ }
297+ if ! foundCreate || ! foundResume {
298+ t .Fatalf ("Expected create and resume requests, got %+v" , capture .Requests )
299+ }
199300 })
200301
201302}
@@ -425,7 +526,7 @@ function handleMessage(message) {
425526 writeResponse(message.id, { message: "pong", protocolVersion: 3, timestamp: Date.now() });
426527 return;
427528 }
428- if (message.method === "session.create") {
529+ if (message.method === "session.create" || message.method === "session.resume" ) {
429530 const sessionId = (message.params && message.params.sessionId) || "fake-session";
430531 writeResponse(message.id, { sessionId, workspacePath: null, capabilities: null });
431532 return;
0 commit comments