|
|
@@ -122,6 +122,59 @@ class ComputerPolicyTests(unittest.TestCase):
|
|
|
self.assertEqual(bridge.computer_directive(session_id='stored', tool_name=tool, args={})['action'], 'block')
|
|
|
self.assertIsNone(bridge.computer_directive(session_id='stored', tool_name='skill_view', args={}))
|
|
|
|
|
|
+ def context_agent(self, session_id='stored'):
|
|
|
+ agent = SimpleNamespace(session_id=session_id, enabled_toolsets=['skills'], disabled_toolsets=[],
|
|
|
+ skip_context_files=False, load_soul_identity=True,
|
|
|
+ _cached_system_prompt='previous-profile-context')
|
|
|
+ agent._invalidate_system_prompt = lambda: setattr(agent, '_cached_system_prompt', None)
|
|
|
+ return agent
|
|
|
+
|
|
|
+ def test_isolated_bind_and_resumed_agent_clear_context_cache_without_changing_history(self):
|
|
|
+ self.session.update(running=False, history=[{'role': 'user', 'content': 'keep-history'}])
|
|
|
+ original = self.context_agent('ordinary-session')
|
|
|
+ body = {'session_id': 'runtime', 'stored_session_id': 'stored', 'profile': 'default',
|
|
|
+ 'bridge_url': self.binding.bridge_url, 'token': self.binding.token,
|
|
|
+ 'expires_at': time.time() * 1000 + 60000, 'computer_policy': self.binding.computer_policy}
|
|
|
+ with patch.object(bridge, '_agent_has_tools', return_value=True):
|
|
|
+ for generation in ['first-turn', 'resumed-turn']:
|
|
|
+ agent = self.context_agent()
|
|
|
+ self.session['agent'] = agent
|
|
|
+ bridge.bind(self.binding.owner, {**body, 'generation': generation})
|
|
|
+ self.assertTrue(agent.skip_context_files)
|
|
|
+ self.assertFalse(agent.load_soul_identity)
|
|
|
+ self.assertIsNone(agent._cached_system_prompt)
|
|
|
+ self.assertEqual(agent.enabled_toolsets, ['skills'])
|
|
|
+ self.assertEqual(self.session['history'], [{'role': 'user', 'content': 'keep-history'}])
|
|
|
+ bridge.unbind(self.binding.owner, {'session_id': 'runtime', 'generation': generation})
|
|
|
+ self.assertTrue(agent.skip_context_files)
|
|
|
+ self.assertFalse(original.skip_context_files)
|
|
|
+ self.assertTrue(original.load_soul_identity)
|
|
|
+
|
|
|
+ def test_isolated_child_inherits_context_policy_and_keeps_skill_tools(self):
|
|
|
+ child = self.context_agent('child-session')
|
|
|
+ self.agent._active_children = [child]
|
|
|
+ tools = [{'function': {'name': name}} for name in ['skills_list', 'skill_view', 'skill_manage']]
|
|
|
+ model_tools = SimpleNamespace(get_tool_definitions=lambda **kw: tools, get_toolset_for_tool=lambda name: 'skills')
|
|
|
+ with patch.dict(sys.modules, {'model_tools': model_tools}):
|
|
|
+ bridge.inherit_child(parent_session_id='stored', child_session_id='child-session')
|
|
|
+ self.assertTrue(child.skip_context_files)
|
|
|
+ self.assertFalse(child.load_soul_identity)
|
|
|
+ self.assertIsNone(child._cached_system_prompt)
|
|
|
+ self.assertEqual(child.valid_tool_names, {'skills_list', 'skill_view', 'skill_manage'})
|
|
|
+
|
|
|
+ def test_context_isolation_preserves_profile_mode_and_requires_supported_agent(self):
|
|
|
+ for policy in [None, {'mode': 'profile', 'hostAccess': True}]:
|
|
|
+ agent = self.context_agent()
|
|
|
+ self.binding.computer_policy = policy
|
|
|
+ bridge._isolate_profile_context(agent, self.binding)
|
|
|
+ self.assertFalse(agent.skip_context_files)
|
|
|
+ self.assertTrue(agent.load_soul_identity)
|
|
|
+ self.assertEqual(agent._cached_system_prompt, 'previous-profile-context')
|
|
|
+ self.binding.computer_policy = {'mode': 'isolated', 'hostAccess': False}
|
|
|
+ with self.assertRaises(bridge.BridgeError) as error:
|
|
|
+ bridge._isolate_profile_context(SimpleNamespace(), self.binding)
|
|
|
+ self.assertEqual(error.exception.code, 'context_isolation_unavailable')
|
|
|
+
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
unittest.main()
|