Spaces:
Sleeping
Sleeping
File size: 9,675 Bytes
1ea26af |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
#!/usr/bin/env python3
"""
Test agent model inheritance - verify WebAgent and FileAgent properly inherit model configs
"""
import os
import sys
import types
import pytest
# Ensure package root is on path
sys.path.insert(0, os.path.abspath('.'))
# Stub heavy dependencies to avoid import overhead
stub_model_mod = types.ModuleType('ck_pro.agents.model')
class _StubLLM:
def __init__(self, _default_init=False, **kwargs):
self.call_target = kwargs.get('call_target', 'https://api.openai.com/v1/chat/completions')
self.api_key = kwargs.get('api_key', 'default-key')
self.model = kwargs.get('model', 'gpt-4o-mini')
self.extract_body = kwargs.get('extract_body', {})
self._default_init = _default_init
def __call__(self, messages):
return "test response"
stub_model_mod.LLM = _StubLLM
sys.modules['ck_pro.agents.model'] = stub_model_mod
# Stub other heavy modules
stub_utils_mod = types.ModuleType('ck_pro.agents.utils')
stub_utils_mod.zwarn = lambda x: None
stub_utils_mod.zlog = lambda x: None
stub_utils_mod.have_images_in_messages = lambda x: False
stub_utils_mod.rprint = lambda x, **kwargs: None
stub_utils_mod.TemplatedString = lambda x: type('T', (), {'format': lambda **k: x})()
stub_utils_mod.parse_response = lambda x: {'code': 'print("ok")'}
stub_utils_mod.CodeExecutor = lambda: type('CE', (), {'run': lambda *a, **k: None, 'get_print_results': lambda: 'ok'})()
stub_utils_mod.KwargsInitializable = object
stub_utils_mod.ActionResult = lambda x: x
sys.modules['ck_pro.agents.utils'] = stub_utils_mod
# Stub agent base
stub_agent_mod = types.ModuleType('ck_pro.agents.agent')
class _StubMultiStepAgent:
def __init__(self, **kwargs):
# Simulate MultiStepAgent behavior: use model from kwargs or default
if 'model' in kwargs:
self.model = _StubLLM(**kwargs['model'])
else:
self.model = _StubLLM(_default_init=True)
self.ACTIVE_FUNCTIONS = {}
stub_agent_mod.MultiStepAgent = _StubMultiStepAgent
stub_agent_mod.register_template = lambda x: None
stub_agent_mod.ActionResult = lambda x: x
sys.modules['ck_pro.agents.agent'] = stub_agent_mod
stub_session_mod = types.ModuleType('ck_pro.agents.session')
stub_session_mod.AgentSession = object
sys.modules['ck_pro.agents.session'] = stub_session_mod
stub_tool_mod = types.ModuleType('ck_pro.agents.tool')
stub_tool_mod.Tool = object
stub_tool_mod.SimpleSearchTool = lambda **kwargs: type('SST', (), {})()
sys.modules['ck_pro.agents.tool'] = stub_tool_mod
# Stub file utils
stub_file_utils_mod = types.ModuleType('ck_pro.ck_file.utils')
stub_file_utils_mod.FileEnv = lambda **kwargs: type('FE', (), {})()
sys.modules['ck_pro.ck_file.utils'] = stub_file_utils_mod
# Stub file prompts
stub_file_prompts_mod = types.ModuleType('ck_pro.ck_file.prompts')
stub_file_prompts_mod.PROMPTS = {}
sys.modules['ck_pro.ck_file.prompts'] = stub_file_prompts_mod
# Stub web prompts
stub_web_prompts_mod = types.ModuleType('ck_pro.ck_web.prompts')
stub_web_prompts_mod.PROMPTS = {}
sys.modules['ck_pro.ck_web.prompts'] = stub_web_prompts_mod
# Import after stubbing
from ck_pro.config.settings import Settings, LLMConfig
from ck_pro.ck_file.agent import FileAgent
from ck_pro.ck_web.agent import WebAgent
class TestAgentModelInheritance:
"""Test that WebAgent and FileAgent properly inherit model configurations"""
def test_file_agent_inherits_main_model_from_kwargs(self):
"""Test FileAgent inherits main model config through kwargs -> super().__init__"""
# Create model config that should be inherited
model_config = {
'call_target': 'https://test.modelscope.cn/v1/chat/completions',
'api_key': 'test-key-123',
'model': 'test-model-456',
'extract_body': {'temperature': 0.3}
}
# Create FileAgent with model config
agent = FileAgent(settings=None, model=model_config)
# Verify main model inherited the config
assert agent.model.call_target == 'https://test.modelscope.cn/v1/chat/completions'
assert agent.model.api_key == 'test-key-123'
assert agent.model.model == 'test-model-456'
assert agent.model.extract_body == {'temperature': 0.3}
def test_file_agent_inherits_multimodal_model_from_kwargs(self):
"""Test FileAgent inherits multimodal model config from model_multimodal kwargs"""
# Create multimodal model config
mm_config = {
'call_target': 'https://test-mm.modelscope.cn/v1/chat/completions',
'api_key': 'test-mm-key',
'model': 'test-mm-model',
'extract_body': {'temperature': 0.0}
}
# Create FileAgent with multimodal config
agent = FileAgent(settings=None, model_multimodal=mm_config)
# Verify multimodal model inherited the config
assert agent.model_multimodal.call_target == 'https://test-mm.modelscope.cn/v1/chat/completions'
assert agent.model_multimodal.api_key == 'test-mm-key'
assert agent.model_multimodal.model == 'test-mm-model'
assert agent.model_multimodal.extract_body == {'temperature': 0.0}
def test_web_agent_inherits_main_model_from_kwargs(self):
"""Test WebAgent inherits main model config through kwargs -> super().__init__"""
# Create model config that should be inherited
model_config = {
'call_target': 'https://test.modelscope.cn/v1/chat/completions',
'api_key': 'test-key-789',
'model': 'test-model-web',
'extract_body': {'temperature': 0.0}
}
# Create WebAgent with model config
agent = WebAgent(settings=None, model=model_config)
# Verify main model inherited the config
assert agent.model.call_target == 'https://test.modelscope.cn/v1/chat/completions'
assert agent.model.api_key == 'test-key-789'
assert agent.model.model == 'test-model-web'
assert agent.model.extract_body == {'temperature': 0.0}
def test_web_agent_inherits_multimodal_model_from_kwargs(self):
"""Test WebAgent inherits multimodal model config from model kwargs (reused)"""
# WebAgent reuses main model config for multimodal
model_config = {
'call_target': 'https://test-web-mm.modelscope.cn/v1/chat/completions',
'api_key': 'test-web-mm-key',
'model': 'test-web-mm-model',
'extract_body': {'temperature': 0.1}
}
# Create WebAgent with model config
agent = WebAgent(settings=None, model=model_config)
# Verify multimodal model inherited the same config
assert agent.model_multimodal.call_target == 'https://test-web-mm.modelscope.cn/v1/chat/completions'
assert agent.model_multimodal.api_key == 'test-web-mm-key'
assert agent.model_multimodal.model == 'test-web-mm-model'
assert agent.model_multimodal.extract_body == {'temperature': 0.1}
def test_file_agent_defaults_when_no_model_config(self):
"""Test FileAgent falls back to defaults when no model config provided"""
# Create FileAgent without model config
agent = FileAgent(settings=None)
# Should use default LLM(_default_init=True) behavior
assert agent.model._default_init == True
assert agent.model_multimodal._default_init == True
def test_web_agent_defaults_when_no_model_config(self):
"""Test WebAgent falls back to defaults when no model config provided"""
# Create WebAgent without model config
agent = WebAgent(settings=None)
# Should use default LLM(_default_init=True) behavior
assert agent.model._default_init == True
assert agent.model_multimodal._default_init == True
def test_full_config_chain_settings_to_agents(self):
"""Test complete config chain: Settings -> CKAgent kwargs -> sub-agents"""
# Create settings with ModelScope endpoints
settings = Settings()
settings.ck.model = LLMConfig(
call_target='https://api-inference.modelscope.cn/v1/chat/completions',
api_key='parent-key',
model='Qwen3-235B-A22B-Instruct-2507'
)
settings.file.model = LLMConfig(
call_target='https://file.modelscope.cn/v1/chat/completions',
api_key='file-key',
model='file-model'
)
settings.web.model = LLMConfig(
call_target='https://web.modelscope.cn/v1/chat/completions',
api_key='web-key',
model='web-model'
)
# Convert to CKAgent kwargs
kwargs = settings.to_ckagent_kwargs()
# Extract sub-agent configs
web_kwargs = kwargs.get('web_agent', {})
file_kwargs = kwargs.get('file_agent', {})
# Create agents with extracted configs
web_agent = WebAgent(settings=settings, **web_kwargs)
file_agent = FileAgent(settings=settings, **file_kwargs)
# Verify web agent got correct config
assert web_agent.model.call_target == 'https://web.modelscope.cn/v1/chat/completions'
assert web_agent.model.api_key == 'web-key'
assert web_agent.model.model == 'web-model'
# Verify file agent got correct config
assert file_agent.model.call_target == 'https://file.modelscope.cn/v1/chat/completions'
assert file_agent.model.api_key == 'file-key'
assert file_agent.model.model == 'file-model'
if __name__ == "__main__":
pytest.main([__file__, "-v"])
|