CB-573: report empty configured profile capacity
This commit is contained in:
@@ -387,7 +387,7 @@ public final class Bridged {
|
||||
profile -> {
|
||||
var configured = config.get().profiles().get(profile);
|
||||
return configured == null ? null : configured.maxLoad();
|
||||
}, System::nanoTime);
|
||||
}, System::nanoTime, () -> config.get().profiles().keySet());
|
||||
|
||||
// CB-559: opt-in config reload. With no `configReload:` block nothing is constructed, so an
|
||||
// upgraded daemon behaves exactly as before — the file is read once at boot and never again.
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.LongSupplier;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -78,6 +79,7 @@ public final class BridgeMcp {
|
||||
private final Function<String, Integer> liveCount;
|
||||
private final Function<String, Integer> maxLoad;
|
||||
private final LongSupplier clock;
|
||||
private final Supplier<Set<String>> configuredProfiles;
|
||||
|
||||
/**
|
||||
* Legacy constructor — no authorization. Retained so existing tests exercise tool behaviour
|
||||
@@ -86,7 +88,7 @@ public final class BridgeMcp {
|
||||
public BridgeMcp(MessageService messages, PeerLauncher workers,
|
||||
SessionManager sessions, ConnectionIdentity identity, MemberPresence presence,
|
||||
PrimaryRegistry primaryRegistry) {
|
||||
this(messages, workers, sessions, identity, presence, primaryRegistry, null, null, _ -> 0, _ -> null, System::nanoTime);
|
||||
this(messages, workers, sessions, identity, presence, primaryRegistry, null, null, _ -> 0, _ -> null, System::nanoTime, Set::of);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,16 +102,17 @@ public final class BridgeMcp {
|
||||
SessionManager sessions, ConnectionIdentity identity, MemberPresence presence,
|
||||
PrimaryRegistry primaryRegistry, CallerResolver callers, Metrics metrics) {
|
||||
this(messages, workers, sessions, identity, presence, primaryRegistry, callers, metrics,
|
||||
_ -> 0, _ -> null, System::nanoTime);
|
||||
_ -> 0, _ -> null, System::nanoTime, Set::of);
|
||||
}
|
||||
|
||||
public BridgeMcp(MessageService messages, PeerLauncher workers, SessionManager sessions,
|
||||
ConnectionIdentity identity, MemberPresence presence, PrimaryRegistry primaryRegistry,
|
||||
CallerResolver callers, Metrics metrics, Function<String, Integer> liveCount,
|
||||
Function<String, Integer> maxLoad, LongSupplier clock) {
|
||||
Function<String, Integer> maxLoad, LongSupplier clock, Supplier<Set<String>> configuredProfiles) {
|
||||
this.liveCount = liveCount;
|
||||
this.maxLoad = maxLoad;
|
||||
this.clock = clock;
|
||||
this.configuredProfiles = configuredProfiles;
|
||||
McpJsonMapper json = new JacksonMcpJsonMapperSupplier().get();
|
||||
this.transport = HttpServletStreamableServerTransportProvider.builder()
|
||||
.jsonMapper(json)
|
||||
@@ -223,7 +226,7 @@ public final class BridgeMcp {
|
||||
.toolCall(listTool(), (exchange, _) -> {
|
||||
McpSchema.CallToolResult denied = deny(exchange, Authz.Action.READ, null);
|
||||
if (denied != null) return denied;
|
||||
return listFleet(workers, sessions, messages, liveCount, maxLoad, clock,
|
||||
return listFleet(workers, sessions, messages, liveCount, maxLoad, clock, configuredProfiles.get(),
|
||||
callers == null ? Map.of() : callers.leads(),
|
||||
callerTerminal(exchange));
|
||||
})
|
||||
@@ -734,12 +737,13 @@ public final class BridgeMcp {
|
||||
*/
|
||||
static McpSchema.CallToolResult listFleet(PeerLauncher workers, SessionManager sessions,
|
||||
Map<String, String> leads, String selfTerm) {
|
||||
return listFleet(workers, sessions, null, _ -> 0, _ -> null, System::nanoTime, leads, selfTerm);
|
||||
return listFleet(workers, sessions, null, _ -> 0, _ -> null, System::nanoTime, Set.of(), leads, selfTerm);
|
||||
}
|
||||
|
||||
static McpSchema.CallToolResult listFleet(PeerLauncher workers, SessionManager sessions, MessageService messages,
|
||||
Function<String, Integer> liveCount, Function<String, Integer> maxLoad,
|
||||
LongSupplier clock, Map<String, String> leads, String selfTerm) {
|
||||
LongSupplier clock, Set<String> configuredProfiles,
|
||||
Map<String, String> leads, String selfTerm) {
|
||||
try {
|
||||
Map<String, Agent> live = workers.list().stream()
|
||||
.map(Agent.class::cast)
|
||||
@@ -753,7 +757,9 @@ public final class BridgeMcp {
|
||||
List<Map<String, Object>> out = roster.stream()
|
||||
.map(s -> memberCapacityView(s, live.get(s.terminalId()), messages, clock.getAsLong()))
|
||||
.toList();
|
||||
List<Map<String, Object>> capacity = roster.stream().map(MemberSession::profile).distinct().sorted()
|
||||
Set<String> profiles = new java.util.TreeSet<>(configuredProfiles);
|
||||
roster.stream().map(MemberSession::profile).forEach(profiles::add);
|
||||
List<Map<String, Object>> capacity = profiles.stream()
|
||||
.map(profile -> capacityView(profile, liveCount, maxLoad, roster, messages, clock.getAsLong()))
|
||||
.toList();
|
||||
return text(json(Map.of("leads", leadRows, "members", out, "capacity", capacity)));
|
||||
|
||||
@@ -348,13 +348,25 @@ class BridgeMcpTest {
|
||||
SessionManager sessions = new SessionManager(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")));
|
||||
sessions.acquire("ltms-local", null, null, null);
|
||||
McpSchema.CallToolResult res = BridgeMcp.listFleet(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")),
|
||||
sessions, null, profile -> 2, profile -> 2, () -> 0, Map.of(), "");
|
||||
sessions, null, profile -> 2, profile -> 2, () -> 0, Set.of("ltms-local"), Map.of(), "");
|
||||
String out = textOf(res);
|
||||
assertTrue(out.contains("\"maxLoad\":2"), out);
|
||||
assertTrue(out.contains("\"live\":2"), out);
|
||||
assertTrue(out.contains("\"free\":0"), out);
|
||||
}
|
||||
|
||||
@Test
|
||||
void capacityIncludesConfiguredProfileWithoutMembers() {
|
||||
FakeHerdr h = new FakeHerdr();
|
||||
SessionManager sessions = new SessionManager(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")));
|
||||
String out = textOf(BridgeMcp.listFleet(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")),
|
||||
sessions, null, profile -> 0, profile -> 2, () -> 0, Set.of("terra"), Map.of(), ""));
|
||||
assertTrue(out.contains("\"profile\":\"terra\""), out);
|
||||
assertTrue(out.contains("\"live\":0"), out);
|
||||
assertTrue(out.contains("\"free\":2"), out);
|
||||
assertTrue(out.contains("\"reclaimable\":0"), out);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listReportsLeadsAndFlagsTheCallersOwnRow() {
|
||||
FakeHerdr h = new FakeHerdr();
|
||||
|
||||
Reference in New Issue
Block a user