learning_ai_common_plat/docs/MCP+A2A/agents/SafetyMonitorAgent.md

5.5 KiB

SafetyMonitorAgent — A2A Spec

Product: NomGap
Trigger: Telemetry event fasting.duration_milestone where hours IN [24, 42, 48, 72], or on-demand via nomgap.safety.check(userId)
Output: Push notification (refeeding_reminder or extended_fast_warning) + structured safety brief logged as telemetry event


Agent roster

Step Agent Input Output
1 FastStateInspectorAgent userId, current timestamp Active fasting session doc + elapsed hours + protocol name
2 ThresholdEvaluatorAgent Fasting session + elapsed hours Safety level (safe / caution / critical) + recommended action
3 SafetyNotificationAgent Safety level + userId + protocol Push notification fired + telemetry event logged
4 ExtendedFastHandoffAgent Session (hours ≥ 48) + safety brief A2A handoff to ExtendedFastDetectionAgent (if escalation needed)

Agent contracts

FastStateInspectorAgent

// Tool: nomgap.fasting.getSession (GET /fasting-sessions/active?userId=<id>)
input: {
  userId: string;
}
output: {
  sessionId: string;
  protocolId: string;
  protocolName: string;
  startedAt: string; // ISO 8601
  elapsedHours: number;
  targetHours: number;
  isActive: boolean;
}

ThresholdEvaluatorAgent

// Pure in-process evaluation — no external calls
// Thresholds defined in nomgap safety rules:
//   0-24h:  safe
//   24-42h: caution (electrolyte reminder at 24h)
//   42-48h: caution (pre-refeeding warning)
//   48h+:   critical (refeeding_reminder + medical supervision flag)
//   72h+:   critical (escalate to ExtendedFastDetectionAgent)
input: {
  sessionId: string;
  elapsedHours: number;
  protocolName: string;
  targetHours: number;
}
output: {
  safetyLevel: 'safe' | 'caution' | 'critical';
  pushType: 'refeeding_reminder' | 'extended_fast_warning' | 'electrolyte_reminder' | null;
  escalate: boolean; // true when elapsedHours >= 72
  messageVariables: Record<string, string>; // { hours, protocolName, refeedingTip }
}

SafetyNotificationAgent

// Tool: nomgap.push.fire (POST platform-service /push-triggers)
// Tool: platform.telemetry.events (POST platform-service /telemetry/events)
input: {
  userId: string;
  pushType: string;
  messageVariables: Record<string, string>;
  sessionId: string;
  safetyLevel: string;
}
output: {
  notified: boolean;
  pushTriggerId: string;
  telemetryEventId: string;
}

ExtendedFastHandoffAgent

// Fires only when ThresholdEvaluatorAgent.escalate === true (hours >= 72)
// A2A handoff artifact is emitted as a telemetry event so any subscribed
// ExtendedFastDetectionAgent can pick it up.
input: {
  userId: string;
  sessionId: string;
  elapsedHours: number;
  safetyLevel: 'critical';
}
output: {
  handoffEventId: string;
  handoffPayload: {
    productId: 'nomgap';
    agentTarget: 'ExtendedFastDetectionAgent';
    userId: string;
    sessionId: string;
    elapsedHours: number;
    triggeredAt: string;
  }
}

Data model

interface SafetyCheckResult {
  userId: string;
  productId: 'nomgap';
  sessionId: string;
  elapsedHours: number;
  safetyLevel: 'safe' | 'caution' | 'critical';
  actionsTaken: string[]; // e.g. ['push:refeeding_reminder', 'telemetry:logged', 'handoff:ExtendedFastDetectionAgent']
  checkedAt: string; // ISO 8601
}

Threshold table

Elapsed hours Safety level Push type Escalate?
< 24 h safe none no
24 h caution electrolyte_reminder no
42 h caution refeeding_reminder no
48 h critical refeeding_reminder no
72 h+ critical extended_fast_warning yes

Error handling

  • If the user has no active fasting session, FastStateInspectorAgent returns isActive: false and the pipeline exits with no action.
  • If nomgap.push.fire fails, the telemetry event is still logged (best-effort notification).
  • If ExtendedFastHandoffAgent cannot emit the handoff event, the critical push notification still fires — escalation failure is non-blocking.
  • Idempotent within a 1-hour window: a safety check that already fired the same pushType within the last 60 minutes is skipped.

MCP tool surface

nomgap.safety.check(userId: string): SafetyCheckResult
nomgap.safety.getThresholds(): ThresholdTable   // returns the threshold table above

Implementation checklist

  • FastStateInspectorAgent — thin wrapper over GET /fasting-sessions/active
  • ThresholdEvaluatorAgent — pure evaluation logic (no I/O), unit-testable
  • SafetyNotificationAgent — calls nomgap.push.fire + logs telemetry event
  • ExtendedFastHandoffAgent — emits A2A handoff telemetry event for ≥ 72 h fasts
  • Cron or event subscription: subscribe to fasting.duration_milestone telemetry events
  • Deduplication guard: skip if same (userId, pushType) fired within 60 minutes
  • MCP tool registration: nomgap.safety.check + nomgap.safety.getThresholds
  • Unit tests for ThresholdEvaluatorAgent covering all 5 threshold rows