test_runtime_environment.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import importlib.util
  2. import sys
  3. import tempfile
  4. import unittest
  5. from contextvars import ContextVar
  6. from pathlib import Path
  7. from types import SimpleNamespace
  8. from unittest.mock import patch
  9. spec = importlib.util.spec_from_file_location('test_yaoyao_environment_bridge', Path(__file__).parents[1] / 'bridge_runtime.py')
  10. bridge = importlib.util.module_from_spec(spec)
  11. sys.modules[spec.name] = bridge
  12. spec.loader.exec_module(bridge)
  13. class RuntimeEnvironmentTests(unittest.TestCase):
  14. def test_capabilities_reports_the_scoped_profile_catalog_without_operating_a_computer(self):
  15. with tempfile.TemporaryDirectory() as directory:
  16. root = Path(directory)
  17. scope = ContextVar('runtime_environment_profile', default=root)
  18. configs = {
  19. root / 'default': {'agent': {'disabled_toolsets': []}},
  20. root / 'limited': {'agent': {'disabled_toolsets': ['terminal', 'computer_use']}},
  21. }
  22. observations = []
  23. def definitions(enabled_toolsets, disabled_toolsets, **kwargs):
  24. observations.append((scope.get(), kwargs))
  25. names = ['yaoyao_tools', 'yaoyao_call', 'terminal', 'read_file', 'computer_use', 'browser_navigate', 'memory', 'yaoyao_desktop_fake']
  26. return [{'function': {'name': name}} for name in names if name not in disabled_toolsets]
  27. modules = {
  28. 'hermes_cli.profiles': SimpleNamespace(get_profile_dir=lambda profile: root / profile, profile_exists=lambda profile: profile in {'default', 'limited'}),
  29. 'hermes_constants': SimpleNamespace(set_hermes_home_override=scope.set, reset_hermes_home_override=scope.reset),
  30. 'hermes_cli.plugins': SimpleNamespace(discover_plugins=lambda: None),
  31. 'hermes_cli.config': SimpleNamespace(load_config=lambda: configs[scope.get()]),
  32. 'model_tools': SimpleNamespace(get_tool_definitions=definitions),
  33. }
  34. with patch.dict(sys.modules, modules), patch.object(bridge, '_web'), \
  35. patch.object(bridge, '_server', return_value=SimpleNamespace(_load_enabled_toolsets=lambda: ['all'])):
  36. full = bridge.capabilities('default')
  37. limited = bridge.capabilities('limited')
  38. self.assertTrue(full['ready'])
  39. facts = full['runtime_environment']
  40. self.assertEqual(facts['profile'], 'default')
  41. self.assertEqual(facts['nativeTools'], {'terminal': ['terminal'], 'files': ['read_file'], 'desktop': ['computer_use'], 'browser': ['browser_navigate']})
  42. self.assertEqual(limited['runtime_environment']['nativeTools'], {'terminal': [], 'files': ['read_file'], 'desktop': [], 'browser': ['browser_navigate']})
  43. self.assertEqual(set(facts), {'version', 'profile', 'platform', 'osRelease', 'arch', 'nativeTools'})
  44. self.assertEqual(scope.get(), root)
  45. self.assertEqual([entry[0] for entry in observations], [root / 'default', root / 'limited'])
  46. self.assertTrue(all(entry[1]['skip_tool_search_assembly'] for entry in observations))
  47. def test_runtime_directory_does_not_report_bridge_tools_as_native_computer_capabilities(self):
  48. definitions = [{'function': {'name': name}} for name in ['yaoyao_tools', 'yaoyao_call', 'yaoyao_desktop_shell_123', 'tool_call', 'tool_describe', 'memory']]
  49. self.assertEqual(bridge._runtime_environment('default', definitions)['nativeTools'], {'terminal': [], 'files': [], 'desktop': [], 'browser': []})
  50. if __name__ == '__main__':
  51. unittest.main()