mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 20:08:18 +08:00
test(agent): exercise real capability gate in ProviderRouter primary-selection tests
This commit is contained in:
parent
5746bcf8cc
commit
b22462105c
@ -10,14 +10,17 @@ import vip.mate.llm.model.ModelConfigEntity;
|
|||||||
import vip.mate.llm.service.ModelCapabilityService;
|
import vip.mate.llm.service.ModelCapabilityService;
|
||||||
import vip.mate.llm.service.ModelCapabilityService.Modality;
|
import vip.mate.llm.service.ModelCapabilityService.Modality;
|
||||||
import vip.mate.llm.service.ModelConfigService;
|
import vip.mate.llm.service.ModelConfigService;
|
||||||
|
import vip.mate.skill.manifest.SkillManifest;
|
||||||
import vip.mate.skill.runtime.SkillRuntimeService;
|
import vip.mate.skill.runtime.SkillRuntimeService;
|
||||||
|
import vip.mate.skill.runtime.model.ResolvedSkill;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@ -45,11 +48,19 @@ class ProviderRouterSelectPrimaryTest {
|
|||||||
when(bindingService.getBoundSkillIds(AGENT_ID)).thenReturn(Set.of());
|
when(bindingService.getBoundSkillIds(AGENT_ID)).thenReturn(Set.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stubCapabilities(String... needs) {
|
/**
|
||||||
// aggregateModelNeeds reads bound skills → return empty so
|
* Bind a single skill that declares the given {@code requires-model}
|
||||||
// resolveRequiredModalities returns null (no capability gate).
|
* tokens, so {@code aggregateModelNeeds} resolves a non-empty capability
|
||||||
// For tests that need capabilities, we stub a bound skill.
|
* set and the capability-gated Pass 1 of {@code selectPrimary} runs.
|
||||||
when(skillRuntimeService.resolveAllSkillsStatus()).thenReturn(List.of());
|
*/
|
||||||
|
private void bindSkillRequiring(String... needs) {
|
||||||
|
when(bindingService.getBoundSkillIds(AGENT_ID)).thenReturn(Set.of(1L));
|
||||||
|
SkillManifest manifest = mock(SkillManifest.class);
|
||||||
|
when(manifest.getRequiresModel()).thenReturn(List.of(needs));
|
||||||
|
ResolvedSkill skill = mock(ResolvedSkill.class);
|
||||||
|
when(skill.getId()).thenReturn(1L);
|
||||||
|
when(skill.getManifest()).thenReturn(manifest);
|
||||||
|
when(skillRuntimeService.resolveAllSkillsStatus()).thenReturn(List.of(skill));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- tests ----
|
// ---- tests ----
|
||||||
@ -71,20 +82,21 @@ class ProviderRouterSelectPrimaryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("2. Preferred provider satisfying capability wins in pass 1")
|
@DisplayName("2. Preferred provider satisfying the required capability wins in pass 1")
|
||||||
void preferredSatisfyingCapabilityWins() {
|
void preferredSatisfyingCapabilityWins() {
|
||||||
when(bindingService.getBoundSkillIds(AGENT_ID)).thenReturn(Set.of(1L));
|
bindSkillRequiring("vision");
|
||||||
// No resolved skills → aggregateModelNeeds returns empty → no capability gate
|
|
||||||
when(skillRuntimeService.resolveAllSkillsStatus()).thenReturn(List.of());
|
|
||||||
when(bindingService.getPreferredProviderIds(AGENT_ID)).thenReturn(List.of("deepseek"));
|
when(bindingService.getPreferredProviderIds(AGENT_ID)).thenReturn(List.of("deepseek"));
|
||||||
when(modelConfigService.getDefaultModelByProvider("deepseek"))
|
when(modelConfigService.getDefaultModelByProvider("deepseek"))
|
||||||
.thenReturn(model("deepseek", "deepseek-chat"));
|
.thenReturn(model("deepseek", "deepseek-vl"));
|
||||||
|
when(capabilityService.resolve(eq("deepseek-vl"), any()))
|
||||||
|
.thenReturn(EnumSet.of(Modality.VISION));
|
||||||
|
|
||||||
ModelConfigEntity global = model("openai", "gpt-4o");
|
ModelConfigEntity global = model("openai", "gpt-4o");
|
||||||
ModelConfigEntity result = router.selectPrimary(AGENT_ID, global);
|
ModelConfigEntity result = router.selectPrimary(AGENT_ID, global);
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals("deepseek", result.getProvider());
|
assertEquals("deepseek", result.getProvider());
|
||||||
|
assertEquals("deepseek-vl", result.getModelName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -149,4 +161,25 @@ class ProviderRouterSelectPrimaryTest {
|
|||||||
ModelConfigEntity result = router.selectPrimary(AGENT_ID, null);
|
ModelConfigEntity result = router.selectPrimary(AGENT_ID, null);
|
||||||
assertNull(result);
|
assertNull(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("8. Preferred misses required capability but global satisfies → global wins in pass 1")
|
||||||
|
void preferredMissesCapabilityGlobalSatisfies() {
|
||||||
|
bindSkillRequiring("vision");
|
||||||
|
when(bindingService.getPreferredProviderIds(AGENT_ID)).thenReturn(List.of("deepseek"));
|
||||||
|
when(modelConfigService.getDefaultModelByProvider("deepseek"))
|
||||||
|
.thenReturn(model("deepseek", "deepseek-chat"));
|
||||||
|
when(capabilityService.resolve(eq("deepseek-chat"), any()))
|
||||||
|
.thenReturn(EnumSet.noneOf(Modality.class));
|
||||||
|
|
||||||
|
ModelConfigEntity global = model("openai", "gpt-4o");
|
||||||
|
when(capabilityService.resolve(eq("gpt-4o"), any()))
|
||||||
|
.thenReturn(EnumSet.of(Modality.VISION));
|
||||||
|
|
||||||
|
ModelConfigEntity result = router.selectPrimary(AGENT_ID, global);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals("openai", result.getProvider());
|
||||||
|
assertEquals("gpt-4o", result.getModelName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user