feat: restore agent capabilities from heartbeat after server restart
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 40s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s

The heartbeat now carries capabilities (per protocol v2 update).
On each heartbeat, capabilities are updated in the agent registry.
On auto-heal (server restart), capabilities from the heartbeat
are used instead of empty Map.of(), so the agent's feature flags
(replay, routeControl, logForwarding, etc.) are restored
immediately on the first heartbeat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-04 13:19:15 +02:00
parent abed4dc96f
commit 45a74075a1
3 changed files with 19 additions and 4 deletions

View File

@@ -201,15 +201,17 @@ public class AgentRegistrationController {
public ResponseEntity<Void> heartbeat(@PathVariable String id,
@RequestBody(required = false) HeartbeatRequest request,
HttpServletRequest httpRequest) {
boolean found = registryService.heartbeat(id);
Map<String, Object> capabilities = request != null ? request.getCapabilities() : null;
boolean found = registryService.heartbeat(id, capabilities);
if (!found) {
// Auto-heal: re-register agent from JWT claims after server restart
var jwtResult = (JwtService.JwtValidationResult) httpRequest.getAttribute(
JwtAuthenticationFilter.JWT_RESULT_ATTR);
if (jwtResult != null) {
String application = jwtResult.application() != null ? jwtResult.application() : "default";
Map<String, Object> caps = capabilities != null ? capabilities : Map.of();
registryService.register(id, id, application, "unknown",
List.of(), Map.of());
List.of(), caps);
registryService.heartbeat(id);
log.info("Auto-registered agent {} (app={}) from heartbeat after server restart", id, application);
} else {