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