"use strict";
/**
 * GoogleAdkAdapter -- Orchestrator adapter for the Google Agent Development Kit (ADK).
 *
 * Hook surface: Google ADK exposes agent lifecycle events that this adapter
 * intercepts at the TypeScript governance layer. Customers wire the adapter by
 * calling the six lifecycle methods at the corresponding points in their ADK
 * integration:
 *
 *   const adapter = new GoogleAdkAdapter(cfg);
 *   adapter.initialize(orchCfg);
 *
 *   // At agent spawn:
 *   await adapter.agentStart(sessionId, userId, contextSnapshot);
 *
 *   // Before every tool invocation:
 *   await adapter.toolCall(sessionId, toolName, toolSpec, args);
 *
 *   // After every tool result returns:
 *   await adapter.toolResult(sessionId, toolName, result);
 *
 *   // Before the agent sends a message to Gemini via Vertex AI:
 *   await adapter.llmCall(sessionId, model, messages, tools);
 *
 *   // After the Gemini response arrives:
 *   await adapter.llmResult(sessionId, model, response);
 *
 *   // When the agent terminates:
 *   await adapter.agentEnd(sessionId, outcome);
 *
 * ADK runtime contexts:
 *   Google ADK agents run on Vertex AI Agent Engine, Cloud Run, GKE, and
 *   Bedrock AgentCore (cross-cloud). Our adapter is the TypeScript governance
 *   layer that consumes ADK-native event payloads regardless of runtime.
 *
 * Provider compliance:
 *   ADK agents call Gemini via Vertex AI. The Google provider compliance
 *   entry (providerId: 'google', baaPath: 'vertex-ai-only') is reused here.
 *   BAA coverage is only valid when Vertex AI is the invocation path; direct
 *   Gemini API calls (AI Studio) do NOT carry a BAA. The adapter enforces
 *   this distinction via the vertexAiRequired flag.
 *
 * Session context:
 *   ADK carries conversation state via session_id and user_id. Both values
 *   are surfaced in every canonical audit event to maintain traceability.
 *
 * Tool normalization:
 *   ADK tool specs use a different format from LangGraph (function declarations
 *   vs JSON schema tool definitions). The adapter normalises both to the
 *   canonical tool-spec shape before emitting audit events.
 *
 * No live Google ADK Python SDK installed. All framework surfaces are shims.
 * TypeScript governance layer only. DEFERRED-ADK-V1-API marker: verify the
 * exact ADK hook surface when the Python SDK stabilises (beta as of 2026-04-23).
 *
 * Spec: P3-SUB-ADAPT-02
 * @connexum/ai-governance
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleAdkAdapter = exports.VERTEX_AI_BAA_REGIONS = exports.AdkSubscriptionGateError = exports.AdkBaaRegionError = exports.AdkUnboundDataError = void 0;
const crypto = __importStar(require("crypto"));
const base_1 = require("./base");
const index_1 = require("./index");
const index_2 = require("../adapters/index");
const index_3 = require("../errors/index");
Object.defineProperty(exports, "AdkUnboundDataError", { enumerable: true, get: function () { return index_3.AdkUnboundDataError; } });
/** Thrown when a Vertex AI region is used that is NOT on the HIPAA BAA-covered list. */
class AdkBaaRegionError extends Error {
    sessionId;
    region;
    constructor(sessionId, region) {
        super(`ADK session "${sessionId}" attempted to call Vertex AI in region "${region}" ` +
            'which is NOT on the HIPAA BAA-covered Vertex AI region list. ' +
            'Block per HIPAA pack provider compliance (google baaPath: vertex-ai-only).');
        this.name = 'AdkBaaRegionError';
        this.sessionId = sessionId;
        this.region = region;
    }
}
exports.AdkBaaRegionError = AdkBaaRegionError;
/** Thrown when the subscription gate blocks an ADK agent. */
class AdkSubscriptionGateError extends Error {
    sessionId;
    constructor(sessionId, reason) {
        super(`ADK subscription gate denied agent for session "${sessionId}": ${reason}`);
        this.name = 'AdkSubscriptionGateError';
        this.sessionId = sessionId;
    }
}
exports.AdkSubscriptionGateError = AdkSubscriptionGateError;
// ---------------------------------------------------------------------------
// HIPAA BAA-covered Vertex AI regions
//
// Source: Google Cloud HIPAA-compliant products and services.
// DEFERRED-ADK-V1-API: Verify against
// https://cloud.google.com/security/compliance/hipaa-compliance when ADK
// stabilises. Vera / Legal must re-verify before any production HIPAA deploy.
// ---------------------------------------------------------------------------
/**
 * Vertex AI regions with documented HIPAA BAA coverage.
 * Any region not in this set triggers AdkBaaRegionError under a HIPAA binding.
 */
exports.VERTEX_AI_BAA_REGIONS = new Set([
    'us-central1',
    'us-east1',
    'us-east4',
    'us-west1',
    'us-west4',
    'northamerica-northeast1',
    'northamerica-northeast2',
    'europe-west1',
    'europe-west2',
    'europe-west3',
    'europe-west4',
]);
// ---------------------------------------------------------------------------
// GoogleAdkAdapter
// ---------------------------------------------------------------------------
class GoogleAdkAdapter extends base_1.BaseOrchestratorAdapter {
    adapterId = 'google-adk';
    orchestratorId = 'google-adk';
    adkConfig;
    /** Per-session tool call counters for runaway detection. */
    toolCallCounters = new Map();
    /** Active sessions: sessionId -> contextSnapshot */
    activeSessions = new Map();
    constructor(config) {
        super();
        this.adkConfig = {
            enforcePackBinding: true,
            enforceVertexAiPath: true,
            ...config,
        };
    }
    // ---------------------------------------------------------------------------
    // agentStart -- gate at ADK agent session spawn
    // ---------------------------------------------------------------------------
    /**
     * Called when an ADK agent session starts. Runs:
     *   1. Session registration check (fail-closed on unregistered sessions)
     *   2. Subscription gate proxy (non-empty registeredSessions)
     *   3. Pack-binding resolver (AdkUnboundDataError if binding is empty)
     *   4. Vertex AI path enforcement (blocks AI Studio calls under HIPAA)
     *   5. BAA region check (AdkBaaRegionError if region not BAA-covered under HIPAA)
     *   6. Provider compliance check for Gemini model
     *
     * Throws AdkSubscriptionGateError, AdkUnboundDataError, AdkBaaRegionError, or
     * OrchestratorError if denied. Returns WorkflowDecision.ALLOW on success.
     *
     * Session context: session_id and user_id are surfaced in every audit event
     * per ADK's session tracking model.
     */
    async agentStart(sessionId, userId, contextSnapshot) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        // -- Circuit breaker -------------------------------------------------------
        if (this.isCircuitOpen()) {
            const reason = 'Circuit breaker is open; ADK agent session denied';
            this.emitCanonical('orchestrator:task-denied', { sessionId, userId, reason });
            this.recordFailure();
            throw new index_1.OrchestratorError({
                message: reason,
                code: 'GOOGLE_ADK_CIRCUIT_OPEN',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Session registration check -------------------------------------------
        const isRegistered = this.adkConfig.registeredSessions.length === 0
            ? false
            : this.adkConfig.registeredSessions.some((prefix) => sessionId.startsWith(prefix));
        if (!isRegistered) {
            const reason = `ADK session "${sessionId}" is not registered (no matching prefix in registeredSessions)`;
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                userId,
                reason,
                registeredPrefixes: this.adkConfig.registeredSessions,
            });
            this.recordFailure();
            throw new AdkSubscriptionGateError(sessionId, reason);
        }
        // -- Pack-binding resolver -------------------------------------------------
        if (this.adkConfig.enforcePackBinding !== false &&
            (!contextSnapshot.packBinding || contextSnapshot.packBinding.length === 0)) {
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                userId,
                reason: 'Missing pack binding at ADK agentStart',
            });
            this.recordFailure();
            throw new index_3.AdkUnboundDataError(sessionId, 'agentStart');
        }
        // -- Vertex AI path enforcement (HIPAA binding) ---------------------------
        const hipaaActive = contextSnapshot.packBinding.some((p) => p.toLowerCase().includes('hipaa') || p.toLowerCase().includes('hitech'));
        if (hipaaActive && this.adkConfig.enforceVertexAiPath !== false) {
            if (!contextSnapshot.isVertexAiPath) {
                const reason = `ADK session "${sessionId}" is using direct AI Studio path (isVertexAiPath=false) ` +
                    'but HIPAA pack requires Vertex AI path for BAA coverage (google baaPath: vertex-ai-only).';
                this.emitCanonical('orchestrator:task-denied', {
                    sessionId,
                    userId,
                    packBinding: contextSnapshot.packBinding,
                    isVertexAiPath: contextSnapshot.isVertexAiPath,
                    reason,
                });
                this.recordFailure();
                throw new AdkBaaRegionError(sessionId, 'ai-studio-direct');
            }
            // -- BAA region check (Vertex AI) ----------------------------------------
            if (!exports.VERTEX_AI_BAA_REGIONS.has(contextSnapshot.vertexRegion)) {
                const reason = `Vertex AI region "${contextSnapshot.vertexRegion}" is not on the HIPAA BAA-covered ` +
                    `region list. Covered regions: [${[...exports.VERTEX_AI_BAA_REGIONS].join(', ')}].`;
                this.emitCanonical('orchestrator:task-denied', {
                    sessionId,
                    userId,
                    vertexRegion: contextSnapshot.vertexRegion,
                    packBinding: contextSnapshot.packBinding,
                    reason,
                });
                this.recordFailure();
                throw new AdkBaaRegionError(sessionId, contextSnapshot.vertexRegion);
            }
        }
        // -- Provider compliance check (approved Gemini model list) ---------------
        if (!this.adkConfig.approvedModels.includes(contextSnapshot.model)) {
            const reason = `Gemini model "${contextSnapshot.model}" is not on the approved model list ` +
                `for pack binding [${contextSnapshot.packBinding.join(', ')}].`;
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                userId,
                model: contextSnapshot.model,
                approvedModels: this.adkConfig.approvedModels,
                reason,
            });
            this.recordFailure();
            throw new index_1.OrchestratorError({
                message: reason,
                code: 'GOOGLE_ADK_UNAPPROVED_MODEL',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Register active session ----------------------------------------------
        this.activeSessions.set(sessionId, contextSnapshot);
        this.toolCallCounters.set(sessionId, 0);
        // -- Emit canonical spawn event (session_id + user_id in every event) -----
        this.emitCanonical('orchestrator:workflow-start', {
            sessionId,
            userId,
            model: contextSnapshot.model,
            packBinding: contextSnapshot.packBinding,
            vertexRegion: contextSnapshot.vertexRegion,
            isVertexAiPath: contextSnapshot.isVertexAiPath,
            parentSessionId: contextSnapshot.parentSessionId ?? null,
            auditId,
        });
        this.recordSuccess();
        return {
            type: 'ALLOW',
            reason: `ADK session "${sessionId}" (user: ${userId}) approved (pack: ${contextSnapshot.packBinding.join(',')})`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // toolCall -- pre-tool gate
    // ---------------------------------------------------------------------------
    /**
     * Called before every ADK tool invocation.
     *   1. Active-session check
     *   2. Pack-binding presence
     *   3. Runaway-session counter
     *   4. Sensitive-tool REQUIRE_APPROVAL routing
     *   5. Exfiltration scan on sensitive argument keys
     *   6. ADK tool-spec normalization (FunctionDeclaration -> canonical)
     *
     * Session_id and user_id travel through every audit event.
     */
    async toolCall(sessionId, toolName, toolSpec, args) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        // -- Active-session check -------------------------------------------------
        if (!this.activeSessions.has(sessionId)) {
            const reason = `ADK session "${sessionId}" called toolCall without agentStart`;
            this.emitCanonical('orchestrator:task-denied', { sessionId, toolName, reason });
            this.recordFailure();
            throw new AdkSubscriptionGateError(sessionId, reason);
        }
        // -- Pack-binding check ---------------------------------------------------
        const snapshot = this.activeSessions.get(sessionId);
        if (this.adkConfig.enforcePackBinding !== false &&
            (!snapshot.packBinding || snapshot.packBinding.length === 0)) {
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                userId: undefined,
                toolName,
                reason: 'Missing pack binding at ADK toolCall',
            });
            this.recordFailure();
            throw new index_3.AdkUnboundDataError(sessionId, `toolCall(${toolName})`);
        }
        // -- Runaway counter ------------------------------------------------------
        const callCount = (this.toolCallCounters.get(sessionId) ?? 0) + 1;
        this.toolCallCounters.set(sessionId, callCount);
        const maxCalls = this.adkConfig.maxToolCallsPerSession;
        if (maxCalls !== undefined && callCount > maxCalls) {
            const reason = `ADK session "${sessionId}" exceeded maxToolCallsPerSession (${maxCalls}). ` +
                'Runaway agent suppressed.';
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                toolName,
                callCount,
                reason,
            });
            this.recordFailure();
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        // -- Exfiltration scan on sensitive argument keys -------------------------
        const exfilHit = this.scanArgsForExfiltration(args);
        if (exfilHit) {
            const reason = `Possible data exfiltration detected in ADK tool args for "${toolName}" ` +
                `(key: "${exfilHit}"). Blocked at G5/G7 egress guard.`;
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                toolName,
                exfilHit,
                reason,
            });
            this.recordFailure();
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        // -- Sensitive-tool approval routing (REQUIRE_APPROVAL) -------------------
        if (this.adkConfig.sensitiveTools.includes(toolName)) {
            const tier = 'human-reviewer';
            const queueId = this.config.reviewerQueues[tier];
            if (!queueId) {
                const reason = `ADK tool "${toolName}" is sensitive but no human-reviewer queue binding exists. ` +
                    'Fail closed.';
                this.emitCanonical('orchestrator:task-denied', { sessionId, toolName, reason });
                this.recordFailure();
                return { type: index_2.ActionDecisionType.DENY, reason, auditId };
            }
            this.emitCanonical('orchestrator:reviewer-routed', {
                sessionId,
                toolName,
                toolSpec: this.normalizeToolSpec(toolSpec),
                tier,
                queueId,
                layer: 'google-adk',
            });
            return {
                type: index_2.ActionDecisionType.REQUIRE_APPROVAL,
                reason: `ADK tool "${toolName}" requires human-reviewer approval`,
                auditId,
                metadata: {
                    reviewerTier: tier,
                    layer: 'google-adk',
                    sessionId,
                    toolName,
                    normalizedSpec: this.normalizeToolSpec(toolSpec),
                },
            };
        }
        // -- Approve ---------------------------------------------------------------
        this.emitCanonical('orchestrator:task-approved', {
            sessionId,
            toolName,
            normalizedSpec: this.normalizeToolSpec(toolSpec),
            callCount,
            layer: 'google-adk',
        });
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `ADK tool "${toolName}" approved for session "${sessionId}"`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // toolResult -- post-tool audit + classifier re-check
    // ---------------------------------------------------------------------------
    /**
     * Called after every ADK tool result is returned.
     * Emits a post-tool audit event and performs an output classifier re-check.
     * Session_id travels through the event for traceability.
     */
    async toolResult(sessionId, toolName, result) {
        this.assertInitialized();
        const outputString = typeof result.output === 'string'
            ? result.output
            : JSON.stringify(result.output ?? '');
        const hasSuspiciousOutput = this.containsPhiPattern(outputString);
        this.emitCanonical('orchestrator:plan-step-end', {
            sessionId,
            toolName,
            success: result.success,
            durationMs: result.durationMs ?? null,
            suspiciousOutput: hasSuspiciousOutput,
            layer: 'google-adk',
        });
        if (hasSuspiciousOutput) {
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                toolName,
                reason: 'Output classifier re-check: possible PHI/PAN detected in ADK tool result. ' +
                    'Surfaced to compliance review queue.',
                layer: 'post-tool-classifier',
            });
        }
    }
    // ---------------------------------------------------------------------------
    // llmCall -- pre-LLM gate
    // ---------------------------------------------------------------------------
    /**
     * Called before the ADK agent sends messages to Gemini via Vertex AI.
     *   1. Active-session check
     *   2. Pack-binding presence
     *   3. Provider-compliance check (approved Gemini model list)
     *   4. Vertex AI path re-verification (HIPAA binding)
     *
     * Session_id travels through the audit event.
     */
    async llmCall(sessionId, model, messages, tools) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        // -- Active-session check -------------------------------------------------
        if (!this.activeSessions.has(sessionId)) {
            const reason = `ADK session "${sessionId}" called llmCall without agentStart`;
            this.emitCanonical('orchestrator:task-denied', { sessionId, model, reason });
            this.recordFailure();
            throw new AdkSubscriptionGateError(sessionId, reason);
        }
        // -- Pack-binding check ---------------------------------------------------
        const snapshot = this.activeSessions.get(sessionId);
        if (this.adkConfig.enforcePackBinding !== false &&
            (!snapshot.packBinding || snapshot.packBinding.length === 0)) {
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                model,
                reason: 'Missing pack binding at ADK llmCall',
            });
            this.recordFailure();
            throw new index_3.AdkUnboundDataError(sessionId, `llmCall(${model})`);
        }
        // -- Provider compliance check (approved Gemini model list) ---------------
        if (!this.adkConfig.approvedModels.includes(model)) {
            const reason = `Gemini model "${model}" is not on the approved provider list for ` +
                `pack binding [${snapshot.packBinding.join(', ')}].`;
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                model,
                packBinding: snapshot.packBinding,
                approvedModels: this.adkConfig.approvedModels,
                reason,
            });
            this.recordFailure();
            throw new index_1.OrchestratorError({
                message: reason,
                code: 'GOOGLE_ADK_UNAPPROVED_MODEL',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Approve LLM call -----------------------------------------------------
        this.emitCanonical('orchestrator:plan-step-begin', {
            sessionId,
            model,
            messageCount: messages.length,
            toolCount: tools.length,
            packBinding: snapshot.packBinding,
            vertexRegion: snapshot.vertexRegion,
            layer: 'google-adk',
        });
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `ADK LLM call to "${model}" approved for session "${sessionId}"`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // llmResult -- post-LLM ingress classify + output-exfiltration scanner
    // ---------------------------------------------------------------------------
    /**
     * Called after the Gemini response arrives.
     * Runs output-exfiltration scanner on response content.
     * Session_id travels through the audit event.
     */
    async llmResult(sessionId, model, response) {
        this.assertInitialized();
        // Flatten Gemini candidate parts to string for scanning
        const responseText = (response.candidates ?? [])
            .flatMap((c) => c.content?.parts ?? [])
            .map((p) => (typeof p.text === 'string' ? p.text : ''))
            .join(' ');
        const hasExfil = this.containsPhiPattern(responseText);
        this.emitCanonical('orchestrator:plan-step-end', {
            sessionId,
            model,
            finishReason: response.finishReason ?? null,
            promptTokenCount: response.usageMetadata?.promptTokenCount ?? null,
            candidatesTokenCount: response.usageMetadata?.candidatesTokenCount ?? null,
            outputExfiltrationFlag: hasExfil,
            layer: 'llm-result',
        });
        if (hasExfil) {
            this.emitCanonical('orchestrator:task-denied', {
                sessionId,
                model,
                reason: 'Output exfiltration scanner: possible PHI/PAN in Gemini/ADK response. ' +
                    'Flagged for compliance review.',
                layer: 'post-llm-classifier',
            });
        }
    }
    // ---------------------------------------------------------------------------
    // agentEnd -- terminal audit event sealing
    // ---------------------------------------------------------------------------
    /**
     * Called when an ADK session terminates (success or failure).
     * Seals the terminal audit event and cleans up tracking state.
     * Session_id and user_id travel through the event.
     */
    async agentEnd(sessionId, outcome) {
        this.assertInitialized();
        const snapshot = this.activeSessions.get(sessionId);
        const toolCallCount = this.toolCallCounters.get(sessionId) ?? 0;
        this.emitCanonical('orchestrator:workflow-complete', {
            sessionId,
            success: outcome.success,
            summary: outcome.summary ?? (outcome.success ? 'ADK session complete' : 'ADK session failed'),
            durationMs: outcome.durationMs ?? null,
            error: outcome.error ?? null,
            toolCallCount,
            packBinding: snapshot?.packBinding ?? [],
            model: snapshot?.model ?? null,
            vertexRegion: snapshot?.vertexRegion ?? null,
        });
        // Clean up session tracking
        this.activeSessions.delete(sessionId);
        this.toolCallCounters.delete(sessionId);
        if (outcome.success) {
            this.recordSuccess();
        }
        else {
            this.recordFailure();
        }
    }
    // ---------------------------------------------------------------------------
    // Private helpers
    // ---------------------------------------------------------------------------
    /**
     * Normalize an ADK FunctionDeclaration tool spec to a canonical shape.
     * ADK uses Google's function_declarations format; we flatten to name + description
     * for audit event payloads.
     */
    normalizeToolSpec(spec) {
        return {
            name: spec.name,
            description: spec.description ?? null,
            parameterKeys: spec.parameters
                ? Object.keys(spec.parameters.properties ?? {})
                : [],
        };
    }
    /**
     * Scan tool call arguments for potential exfiltration patterns.
     * Returns the first sensitive key found, or null if clean.
     */
    scanArgsForExfiltration(args) {
        for (const key of this.adkConfig.sensitiveArgKeys) {
            const value = args[key];
            if (typeof value === 'string' && this.containsPhiPattern(value)) {
                return key;
            }
        }
        return null;
    }
    /**
     * Heuristic PHI / PAN pattern check.
     * Mirrors the DataClassifier patterns at a lightweight level.
     */
    containsPhiPattern(text) {
        // SSN pattern: 3-2-4 digit groups
        if (/\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b/.test(text))
            return true;
        // PAN (credit card): 13-19 consecutive digits
        if (/\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{1,4}\b/.test(text))
            return true;
        // Obvious PHI keywords in data payloads
        if (/\b(patient_id|mrn|dob|date_of_birth|diagnosis|ssn|npi)\s*[:=]/i.test(text))
            return true;
        return false;
    }
    // ---------------------------------------------------------------------------
    // OrchestratorAdapter surface -- workflow lifecycle wrappers
    // ---------------------------------------------------------------------------
    async startWorkflow(ctx) {
        const auditId = crypto.randomUUID();
        this.emitCanonical('orchestrator:workflow-start', {
            workflowId: ctx.workflowId,
            name: ctx.name,
            initiator: ctx.initiator.name,
        });
        return { type: 'ALLOW', reason: 'Google ADK workflow started', auditId };
    }
    async stepWorkflow(ctx) {
        const auditId = crypto.randomUUID();
        this.emitCanonical('orchestrator:plan-step-begin', {
            workflowId: ctx.workflowId,
            stepId: ctx.stepId,
            stepIndex: ctx.stepIndex,
        });
        if (this.isCircuitOpen()) {
            this.emitCanonical('orchestrator:circuit-breaker-tripped', {
                workflowId: ctx.workflowId,
                stepId: ctx.stepId,
            });
            return { type: 'DENY', reason: 'Circuit breaker is open', auditId };
        }
        return { type: 'ALLOW', reason: 'Step permitted', auditId };
    }
    async completeWorkflow(ctx, result) {
        this.emitCanonical('orchestrator:workflow-complete', {
            workflowId: ctx.workflowId,
            success: result.success,
            summary: result.summary,
            durationMs: result.durationMs,
        });
    }
    // ---------------------------------------------------------------------------
    // Task / plan / delegation surfaces (required by BaseOrchestratorAdapter)
    // ---------------------------------------------------------------------------
    async preTask(task) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        if (this.isCircuitOpen()) {
            const reason = 'Circuit breaker is open; task denied';
            this.emitCanonical('orchestrator:task-denied', { taskId: task.taskId, reason });
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        this.emitCanonical('orchestrator:task-approved', {
            taskId: task.taskId,
            agentName: task.assignedAgent.name,
        });
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `Task "${task.taskId}" approved via GoogleAdkAdapter`,
            auditId,
        };
    }
    async postTask(task, result) {
        this.emitCanonical('orchestrator:plan-step-end', { taskId: task.taskId, result });
    }
    async prePlan(plan) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        this.emitCanonical('orchestrator:plan-proposed', { planId: plan.planId });
        try {
            this.validatePlanStructure(plan);
        }
        catch (err) {
            const reason = err instanceof Error ? err.message : String(err);
            this.emitCanonical('orchestrator:plan-denied', { planId: plan.planId, reason });
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        this.emitCanonical('orchestrator:plan-approved', { planId: plan.planId });
        return { type: index_2.ActionDecisionType.ALLOW, reason: 'Plan approved', auditId };
    }
    async postPlan(plan, result) {
        this.emitCanonical('orchestrator:workflow-complete', { planId: plan.planId, result });
    }
    async preDelegation(d) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        const restricted = d.permissions.filter((p) => this.adkConfig.sensitiveTools.includes(p));
        if (restricted.length > 0) {
            const reason = `ADK delegation includes restricted permissions: ${restricted.join(', ')}`;
            this.emitCanonical('orchestrator:delegation-denied', {
                delegationId: d.delegationId,
                from: d.fromAgent.name,
                to: d.toAgent.name,
                restricted,
            });
            return {
                type: index_2.ActionDecisionType.DENY,
                reason,
                restrictedPermissions: restricted,
                auditId,
            };
        }
        this.emitCanonical('orchestrator:delegation-approved', {
            delegationId: d.delegationId,
            from: d.fromAgent.name,
            to: d.toAgent.name,
        });
        return { type: index_2.ActionDecisionType.ALLOW, reason: 'Delegation approved', auditId };
    }
    async postDelegation(d, result) {
        this.emitCanonical('orchestrator:delegation-approved', {
            delegationId: d.delegationId,
            result,
        });
    }
    async invokeRoleEdge(edge) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        this.emitCanonical('orchestrator:role-edge-invoked', {
            edgeId: edge.edgeId,
            fromRole: edge.fromRole,
            toRole: edge.toRole,
        });
        return { type: 'ALLOW', reason: 'Google ADK role edge permitted', auditId };
    }
    // ---------------------------------------------------------------------------
    // Error translation
    // ---------------------------------------------------------------------------
    translateError(raw) {
        if (raw instanceof index_1.OrchestratorError)
            return raw;
        const message = raw instanceof Error ? raw.message : String(raw);
        if (message.includes('AdkBaaRegionError') || message.includes('BAA-covered')) {
            return new index_1.OrchestratorError({
                message: `Google ADK BAA region violation: ${message}`,
                code: 'GOOGLE_ADK_BAA_REGION_VIOLATION',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        if (message.includes('AdkUnboundDataError') || message.includes('pack binding')) {
            return new index_1.OrchestratorError({
                message: `Google ADK unbound data: ${message}`,
                code: 'GOOGLE_ADK_UNBOUND_DATA',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        if (message.includes('GOOGLE_ADK_UNAPPROVED_MODEL') || message.includes('approved model list')) {
            return new index_1.OrchestratorError({
                message: `Google ADK unapproved model: ${message}`,
                code: 'GOOGLE_ADK_UNAPPROVED_MODEL',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        return new index_1.OrchestratorError({
            message,
            code: 'GOOGLE_ADK_ERROR',
            orchestratorId: this.orchestratorId,
            adapterId: this.adapterId,
            raw,
        });
    }
    // ---------------------------------------------------------------------------
    // Capabilities
    // ---------------------------------------------------------------------------
    getOrchestratorCapabilities() {
        return {
            workflowGovernance: true,
            taskGovernance: true,
            planGovernance: true,
            delegationGovernance: true,
            roleEdgeGovernance: true,
            parallelExecution: true,
            nestedPlans: true,
            circuitBreaker: true,
        };
    }
}
exports.GoogleAdkAdapter = GoogleAdkAdapter;
//# sourceMappingURL=google-adk.js.map