Interface ICrossAgentGuardrailService

Cross-agent guardrail service for multi-agent supervision.

Extends IGuardrailService to enable observation and intervention in other agents' output streams. Use this for:

  • Supervisor patterns: A supervisor agent monitors worker agents
  • Quality gates: Enforce quality standards across an agency
  • Policy enforcement: Apply organization-wide rules to all agents
  • Safety monitoring: Detect and prevent harmful outputs from any agent

Example: Quality gate guardrail

class QualityGateGuardrail implements ICrossAgentGuardrailService {
// Observe all agents in the agency
observeAgentIds = [];
canInterruptOthers = true;

async evaluateCrossAgentOutput({ sourceAgentId, chunk, context }) {
if (chunk.type === 'FINAL_RESPONSE') {
const quality = await assessQuality(chunk.finalResponseText);
if (quality.score < 0.5) {
return {
action: GuardrailAction.BLOCK,
reason: 'Response did not meet quality standards',
metadata: { qualityScore: quality.score, agent: sourceAgentId }
};
}
}
return null;
}
}

Example: Selective agent monitoring

class SensitiveDataGuardrail implements ICrossAgentGuardrailService {
// Only observe agents handling sensitive data
observeAgentIds = ['data-analyst', 'report-generator'];
canInterruptOthers = true;
config = { evaluateStreamingChunks: true };

async evaluateCrossAgentOutput({ chunk }) {
if (chunk.textDelta && containsPII(chunk.textDelta)) {
return {
action: GuardrailAction.SANITIZE,
modifiedText: redactPII(chunk.textDelta)
};
}
return null;
}
}
interface ICrossAgentGuardrailService {
    observeAgentIds?: string[];
    canInterruptOthers?: boolean;
    evaluateCrossAgentOutput?(payload): Promise<null | GuardrailEvaluationResult>;
    id?: string;
    stages?: readonly ("output" | "input")[];
    config?: GuardrailConfig;
    evaluateInput?(payload): Promise<null | GuardrailEvaluationResult>;
    evaluateOutput?(payload): Promise<null | GuardrailEvaluationResult>;
}

Hierarchy (view full)

Methods

  • Evaluate agent output before streaming to client.

    Called for each chunk of a guarded output stream (the turn's, and the continuation after an external tool result) that carries isFinal: true (the FINAL_RESPONSE, an ERROR the turn yields), for each TEXT_DELTA chunk when GuardrailConfig.evaluateStreamingChunks is set (real-time filtering), and for each TOOL_CALL_REQUEST chunk when GuardrailConfig.evaluateToolCalls is set. Other chunks are not passed to it, nor is the ERROR that processRequest() yields from its own catch.

    Parameters

    Returns Promise<null | GuardrailEvaluationResult>

    Evaluation result, or null to allow without action

    Remarks

    • Return BLOCK to immediately terminate the stream with an error chunk, or with a FINAL_RESPONSE holding replacementText when the result carries a non-empty one
    • Return SANITIZE with modifiedText to redact/modify content; on a TOOL_CALL_REQUEST chunk it is applied as BLOCK
    • Streaming evaluation adds latency; use only when real-time filtering is required

Properties

observeAgentIds?: string[]

Agent IDs this guardrail observes.

  • Empty array [] or undefined: Observe all agents in the agency
  • Specific IDs: Only observe listed agents

Example

// Observe specific workers
observeAgentIds = ['worker-1', 'worker-2'];

// Observe all agents
observeAgentIds = [];
canInterruptOthers?: boolean

Whether this guardrail can interrupt other agents' streams.

When true:

When false (default):

  • Guardrail can only observe and log (FLAG action)
  • BLOCK/SANITIZE actions are downgraded to FLAG

Default

false
id?: string

A stable id for this guard. A required guard is named by it (AgentOSConfig.requiredGuardrails), and it travels with every verdict as metadata.guardrailId. Without one, a registered guard is known by its descriptor's id.

stages?: readonly ("output" | "input")[]

The stages this guard evaluates, for a guard whose methods say more than its configuration: one that implements both methods but runs on one stage declares that stage. A required guard is held to what it declares, and a stage it does not declare is reported as missing instead of passing on the method's existence. Without it, a stage counts as covered when its method exists.

Configuration for evaluation behavior. Controls streaming vs final-only evaluation and rate limiting.