Merge pull request #976 from Molecule-AI/feat/last-outbound-at-817

feat(platform): track last_outbound_at for silent detection (closes #817)
This commit is contained in:
Hongming Wang 2026-04-19 00:30:01 -07:00 committed by GitHub
commit e2c270600c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 0 deletions

View File

@ -591,6 +591,20 @@ func (h *WorkspaceHandler) logA2ASuccess(ctx context.Context, workspaceID, calle
if wsNameForLog == "" {
wsNameForLog = workspaceID
}
// #817: track outbound activity on the CALLER so orchestrators can detect
// silent workspaces. Only update when callerID is a real workspace (not
// canvas, not a system caller) and the target returned 2xx/3xx.
if callerID != "" && !isSystemCaller(callerID) && statusCode < 400 {
go func() {
bgCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := db.DB.ExecContext(bgCtx,
`UPDATE workspaces SET last_outbound_at = NOW() WHERE id = $1`, callerID); err != nil {
log.Printf("last_outbound_at update failed for %s: %v", callerID, err)
}
}()
}
summary := a2aMethod + " → " + wsNameForLog
go func(parent context.Context) {
logCtx, cancel := context.WithTimeout(context.WithoutCancel(parent), 30*time.Second)

View File

@ -444,6 +444,18 @@ func (h *WorkspaceHandler) Get(c *gin.Context) {
delete(ws, "last_sample_error") // internal error details
delete(ws, "workspace_dir") // host path disclosure
// #817: expose last_outbound_at so orchestrators can detect silent
// workspaces. Non-sensitive — just a timestamp of the most recent
// outbound A2A. Null if the workspace has never sent anything.
var lastOutbound sql.NullTime
if err := db.DB.QueryRowContext(c.Request.Context(),
`SELECT last_outbound_at FROM workspaces WHERE id = $1`, id,
).Scan(&lastOutbound); err == nil && lastOutbound.Valid {
ws["last_outbound_at"] = lastOutbound.Time
} else {
ws["last_outbound_at"] = nil
}
c.JSON(http.StatusOK, ws)
}

View File

@ -0,0 +1,5 @@
-- Issue #817 (sub of #795): track last outbound A2A activity per workspace so
-- PM/Dev Lead can detect workspaces that have gone silent despite being online.
-- The orchestrator compares this against now() in its pulse; > 2 hours with an
-- active cron triggers a phantom-busy warning.
ALTER TABLE workspaces ADD COLUMN IF NOT EXISTS last_outbound_at TIMESTAMPTZ;