switchroom 0.19.28 → 0.19.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -289,7 +289,7 @@ class BoundedRead(unittest.TestCase):
289
289
 
290
290
 
291
291
  class RunSubagentRetain(unittest.TestCase):
292
- def _run(self, hook_input):
292
+ def _run(self, hook_input, config_extra=None):
293
293
  captured = {}
294
294
 
295
295
  class _Client:
@@ -300,7 +300,8 @@ class RunSubagentRetain(unittest.TestCase):
300
300
  captured.update(kwargs)
301
301
  return {"ok": True}
302
302
 
303
- with mock.patch("subagent_retain.load_config", return_value=dict(CONFIG)), \
303
+ config = dict(CONFIG, **(config_extra or {}))
304
+ with mock.patch("subagent_retain.load_config", return_value=config), \
304
305
  mock.patch("subagent_retain.get_api_url", return_value="http://x"), \
305
306
  mock.patch("subagent_retain.ensure_bank_mission"), \
306
307
  mock.patch("subagent_retain.derive_bank_id", return_value="agentbank"), \
@@ -336,6 +337,43 @@ class RunSubagentRetain(unittest.TestCase):
336
337
  self.assertEqual(captured["context"], "claude-code-sidechain")
337
338
  self.assertEqual(captured["metadata"]["parent_session_id"], "parentsess")
338
339
 
340
+ def test_sidechain_retain_omits_the_scope_when_unconfigured(self):
341
+ # switchroom — default behaviour must be byte-identical: the sidechain
342
+ # POST carries no scope, so the engine default stands.
343
+ with tempfile.TemporaryDirectory() as d:
344
+ sc = os.path.join(d, "agent-af5.jsonl")
345
+ _write_sidechain(sc, 8, chars_per_msg=400)
346
+ hook_input = {
347
+ "session_id": "parentsess",
348
+ "agent_id": "af5",
349
+ "agent_transcript_path": sc,
350
+ "transcript_path": os.path.join(d, "parentsess.jsonl"),
351
+ "cwd": d,
352
+ }
353
+ result, captured = self._run(hook_input)
354
+ self.assertEqual(result["status"], "ok")
355
+ self.assertIsNone(captured["observation_scopes"])
356
+
357
+ def test_sidechain_retain_posts_the_configured_scope(self):
358
+ # switchroom — sidechain retains are their own hand-enumerated kwarg
359
+ # list; without this pin they would silently keep per-tag scopes while
360
+ # the parent session's retains moved to the shared one.
361
+ with tempfile.TemporaryDirectory() as d:
362
+ sc = os.path.join(d, "agent-af5.jsonl")
363
+ _write_sidechain(sc, 8, chars_per_msg=400)
364
+ hook_input = {
365
+ "session_id": "parentsess",
366
+ "agent_id": "af5",
367
+ "agent_transcript_path": sc,
368
+ "transcript_path": os.path.join(d, "parentsess.jsonl"),
369
+ "cwd": d,
370
+ }
371
+ result, captured = self._run(
372
+ hook_input, config_extra={"observationScopes": "shared"}
373
+ )
374
+ self.assertEqual(result["status"], "ok")
375
+ self.assertEqual(captured["observation_scopes"], "shared")
376
+
339
377
  def test_document_id_is_stable_across_refires(self):
340
378
  with tempfile.TemporaryDirectory() as d:
341
379
  sc = os.path.join(d, "agent-af5.jsonl")