/**
 * BedrockAgentCoreAdapter -- Orchestrator adapter for AWS Bedrock AgentCore.
 *
 * Hook surface: Bedrock AgentCore is AWS's agent orchestration layer. Agents
 * invoke foundation models through Bedrock (InvokeAgent API). This adapter
 * intercepts at the caller layer (before InvokeAgent fires) and at the
 * response layer:
 *
 *   const adapter = new BedrockAgentCoreAdapter(cfg);
 *   adapter.initialize(orchCfg);
 *
 *   // Before every InvokeAgent call (agentStart equivalent):
 *   await adapter.agentStart(agentId, sessionId, contextSnapshot);
 *
 *   // Before every action group (tool equivalent) invocation:
 *   await adapter.toolCall(agentId, actionGroup, actionSpec, args);
 *
 *   // After every action group result returns:
 *   await adapter.toolResult(agentId, actionGroup, result);
 *
 *   // Before every underlying Bedrock model call:
 *   await adapter.llmCall(agentId, modelId, messages, tools);
 *
 *   // After the model response arrives:
 *   await adapter.llmResult(agentId, modelId, response);
 *
 *   // When the agent run terminates:
 *   await adapter.agentEnd(agentId, outcome);
 *
 * AgentCore-specific surfaces:
 *   - InvokeAgent API: pre-call governance (agentStart) + response governance (agentEnd)
 *   - Action groups: AgentCore's tool concept; maps to toolCall/toolResult hooks
 *   - Knowledge Base retrieval: separate ingress data class, tagged KNOWLEDGE_BASE in audit
 *   - HIPAA BAA region enforcement: Bedrock has BAA coverage in specific AWS regions;
 *     this adapter verifies region compliance before any HIPAA-bound invocation proceeds
 *
 * HIPAA BAA coverage:
 *   AWS Bedrock is covered by the AWS HIPAA BAA in specific regions. Any region
 *   not on the BAA-covered list triggers BedrockBaaRegionError when a HIPAA pack
 *   is bound. Reuses provider compliance metadata from src/llm-adapters/bedrock.ts
 *   (providerId: 'amazon', baa: true).
 *
 * Provider compliance:
 *   Bedrock agents call foundation models through Bedrock. The adapter checks that
 *   the resolved modelId is on the approved model list. Models are identified by
 *   Bedrock model IDs (e.g. 'anthropic.claude-3-5-sonnet-20241022-v2:0').
 *
 * No live AWS Bedrock SDK installed. All framework surfaces are shims.
 * No AWS SDK dependency; matching the pattern from src/llm-adapters/bedrock.ts.
 * DEFERRED-BEDROCK-AGENTCORE-V1: Verify exact InvokeAgent hook surface against
 * AWS SDK for JavaScript v3 @aws-sdk/client-bedrock-agent-runtime at implementation.
 *
 * Spec: P3-SUB-ADAPT-03
 * @connexum/ai-governance
 */
import * as crypto from 'crypto';
import { BaseOrchestratorAdapter } from './base.js';
import { OrchestratorError, } from './index.js';
import { ActionDecisionType } from '../adapters/index.js';
import { BedrockUnboundDataError } from '../errors/index.js';
// ---------------------------------------------------------------------------
// Error classes specific to this adapter
// ---------------------------------------------------------------------------
/** Thrown when an AgentCore invocation targets a region without HIPAA BAA coverage. */
export class BedrockBaaRegionError extends Error {
    agentId;
    region;
    constructor(agentId, region) {
        super(`Bedrock AgentCore agent "${agentId}" attempted to invoke in region "${region}" ` +
            'which is NOT on the HIPAA BAA-covered Bedrock region list. ' +
            'Block per HIPAA pack provider compliance (amazon baa: true, region-restricted).');
        this.name = 'BedrockBaaRegionError';
        this.agentId = agentId;
        this.region = region;
    }
}
/**
 * Thrown when an AgentCore agent attempts to act without a pack binding.
 * Re-exports canonical UnboundDataError as BedrockUnboundDataError so
 * a single `instanceof UnboundDataError` at the server boundary matches
 * all adapter origins. (C2 fix, 2026-04-24)
 */
export { BedrockUnboundDataError };
/** Thrown when a Knowledge Base retrieval contains PHI under a HIPAA binding. */
export class BedrockKbPhiError extends Error {
    agentId;
    knowledgeBaseId;
    constructor(agentId, knowledgeBaseId) {
        super(`Bedrock Knowledge Base retrieval for agent "${agentId}" ` +
            `(knowledgeBaseId: "${knowledgeBaseId}") contains possible PHI. ` +
            'Flagged for HIPAA compliance review. Ingress data class: KNOWLEDGE_BASE.');
        this.name = 'BedrockKbPhiError';
        this.agentId = agentId;
        this.knowledgeBaseId = knowledgeBaseId;
    }
}
// ---------------------------------------------------------------------------
// HIPAA BAA-covered Bedrock regions
//
// Source: AWS Bedrock HIPAA eligibility documentation.
// DEFERRED-BEDROCK-AGENTCORE-V1: Verify against
// https://aws.amazon.com/compliance/hipaa-compliance/ before production deploy.
// Vera / Legal must re-verify. DEFERRED-BEDROCK-ATTEST mirrors the note in
// src/llm-adapters/bedrock.ts.
// ---------------------------------------------------------------------------
/**
 * AWS regions where Bedrock (and thus AgentCore) is covered under the AWS HIPAA BAA.
 * Any region not in this set triggers BedrockBaaRegionError under a HIPAA binding.
 */
export const BEDROCK_BAA_REGIONS = new Set([
    'us-east-1',
    'us-east-2',
    'us-west-2',
    'ca-central-1',
    'eu-west-1',
    'eu-west-2',
    'eu-central-1',
    'ap-southeast-2',
]);
// ---------------------------------------------------------------------------
// BedrockAgentCoreAdapter
// ---------------------------------------------------------------------------
export class BedrockAgentCoreAdapter extends BaseOrchestratorAdapter {
    adapterId = 'bedrock-agentcore';
    orchestratorId = 'bedrock-agentcore';
    agentCoreConfig;
    /** Per-agent action call counters for runaway detection. */
    actionCallCounters = new Map();
    /** Active agents: agentId -> contextSnapshot */
    activeAgents = new Map();
    constructor(config) {
        super();
        this.agentCoreConfig = {
            enforcePackBinding: true,
            enforceHipaaBaaRegion: true,
            ...config,
        };
    }
    // ---------------------------------------------------------------------------
    // agentStart -- gate before InvokeAgent fires
    // ---------------------------------------------------------------------------
    /**
     * Called before every InvokeAgent API call. Runs:
     *   1. Agent registration check (fail-closed on unregistered agents)
     *   2. Pack-binding resolver (BedrockUnboundDataError if binding is empty)
     *   3. HIPAA BAA region check (BedrockBaaRegionError if region not covered)
     *   4. Approved model check for the agent's configured modelId
     *
     * Throws BedrockBaaRegionError, BedrockUnboundDataError, or OrchestratorError
     * if denied. Returns WorkflowDecision.ALLOW on success.
     *
     * SessionId travels through every audit event for traceability.
     */
    async agentStart(agentId, sessionId, contextSnapshot) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        // -- Circuit breaker -------------------------------------------------------
        if (this.isCircuitOpen()) {
            const reason = 'Circuit breaker is open; Bedrock AgentCore invocation denied';
            this.emitCanonical('orchestrator:task-denied', { agentId, sessionId, reason });
            this.recordFailure();
            throw new OrchestratorError({
                message: reason,
                code: 'BEDROCK_AGENTCORE_CIRCUIT_OPEN',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Agent registration check ----------------------------------------------
        if (!this.agentCoreConfig.registeredAgents.includes(agentId)) {
            const reason = `Bedrock AgentCore agent "${agentId}" is not registered. ` +
                `Registered agents: [${this.agentCoreConfig.registeredAgents.join(', ')}].`;
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                sessionId,
                reason,
                registeredAgents: this.agentCoreConfig.registeredAgents,
            });
            this.recordFailure();
            throw new OrchestratorError({
                message: reason,
                code: 'BEDROCK_AGENTCORE_UNREGISTERED_AGENT',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Pack-binding resolver -------------------------------------------------
        if (this.agentCoreConfig.enforcePackBinding !== false &&
            (!contextSnapshot.packBinding || contextSnapshot.packBinding.length === 0)) {
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                sessionId,
                reason: 'Missing pack binding at Bedrock AgentCore agentStart',
            });
            this.recordFailure();
            throw new BedrockUnboundDataError(agentId, 'agentStart');
        }
        // -- HIPAA BAA region check ------------------------------------------------
        const hipaaActive = contextSnapshot.packBinding.some((p) => p.toLowerCase().includes('hipaa') || p.toLowerCase().includes('hitech'));
        if (hipaaActive && this.agentCoreConfig.enforceHipaaBaaRegion !== false) {
            if (!BEDROCK_BAA_REGIONS.has(contextSnapshot.region)) {
                const reason = `Bedrock region "${contextSnapshot.region}" is not on the HIPAA BAA-covered ` +
                    `Bedrock region list. Covered regions: [${[...BEDROCK_BAA_REGIONS].join(', ')}].`;
                this.emitCanonical('orchestrator:task-denied', {
                    agentId,
                    sessionId,
                    region: contextSnapshot.region,
                    packBinding: contextSnapshot.packBinding,
                    reason,
                });
                this.recordFailure();
                throw new BedrockBaaRegionError(agentId, contextSnapshot.region);
            }
        }
        // -- Approved model check --------------------------------------------------
        if (!this.agentCoreConfig.approvedModelIds.includes(contextSnapshot.modelId)) {
            const reason = `Bedrock model "${contextSnapshot.modelId}" is not on the approved model list ` +
                `for pack binding [${contextSnapshot.packBinding.join(', ')}].`;
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                sessionId,
                modelId: contextSnapshot.modelId,
                approvedModelIds: this.agentCoreConfig.approvedModelIds,
                reason,
            });
            this.recordFailure();
            throw new OrchestratorError({
                message: reason,
                code: 'BEDROCK_AGENTCORE_UNAPPROVED_MODEL',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Register active agent ------------------------------------------------
        this.activeAgents.set(agentId, contextSnapshot);
        this.actionCallCounters.set(agentId, 0);
        // -- Emit canonical spawn event -------------------------------------------
        this.emitCanonical('orchestrator:workflow-start', {
            agentId,
            sessionId,
            bedrockAgentId: contextSnapshot.bedrockAgentId,
            agentAliasId: contextSnapshot.agentAliasId,
            region: contextSnapshot.region,
            modelId: contextSnapshot.modelId,
            packBinding: contextSnapshot.packBinding,
            auditId,
        });
        this.recordSuccess();
        return {
            type: 'ALLOW',
            reason: `Bedrock AgentCore agent "${agentId}" (session: ${sessionId}) approved ` +
                `(pack: ${contextSnapshot.packBinding.join(',')}, region: ${contextSnapshot.region})`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // toolCall -- pre-action-group gate
    // ---------------------------------------------------------------------------
    /**
     * Called before every AgentCore action group invocation (the toolCall equivalent).
     *   1. Active-agent check
     *   2. Pack-binding presence
     *   3. Runaway-agent counter
     *   4. Knowledge Base retrieval classification as KNOWLEDGE_BASE ingress data
     *   5. Sensitive action group REQUIRE_APPROVAL routing
     *   6. PHI classifier scan on action arguments (G5 / G7 egress guards)
     *
     * AgentCore distinguishes action groups (Lambda-backed tools) from Knowledge Base
     * retrievals. Both map to this hook surface. Knowledge Base calls are tagged
     * with data class KNOWLEDGE_BASE in the audit event.
     */
    async toolCall(agentId, actionSpec, args) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        const actionName = `${actionSpec.actionGroupName}.${actionSpec.operationName}`;
        // -- Active-agent check ---------------------------------------------------
        if (!this.activeAgents.has(agentId)) {
            const reason = `Bedrock AgentCore agent "${agentId}" called toolCall without agentStart`;
            this.emitCanonical('orchestrator:task-denied', { agentId, actionName, reason });
            this.recordFailure();
            throw new OrchestratorError({
                message: reason,
                code: 'BEDROCK_AGENTCORE_NO_AGENT_START',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Pack-binding check ---------------------------------------------------
        const snapshot = this.activeAgents.get(agentId);
        if (this.agentCoreConfig.enforcePackBinding !== false &&
            (!snapshot.packBinding || snapshot.packBinding.length === 0)) {
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                actionName,
                reason: 'Missing pack binding at Bedrock AgentCore toolCall',
            });
            this.recordFailure();
            throw new BedrockUnboundDataError(agentId, `toolCall(${actionName})`);
        }
        // -- Runaway counter ------------------------------------------------------
        const callCount = (this.actionCallCounters.get(agentId) ?? 0) + 1;
        this.actionCallCounters.set(agentId, callCount);
        const maxCalls = this.agentCoreConfig.maxActionCallsPerRun;
        if (maxCalls !== undefined && callCount > maxCalls) {
            const reason = `Bedrock AgentCore agent "${agentId}" exceeded maxActionCallsPerRun (${maxCalls}). ` +
                'Runaway agent suppressed.';
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                actionName,
                callCount,
                reason,
            });
            this.recordFailure();
            return { type: ActionDecisionType.DENY, reason, auditId };
        }
        // -- Knowledge Base ingress data classification ---------------------------
        // KB retrievals are a distinct data class from action group calls.
        // Tag as KNOWLEDGE_BASE in the audit event payload so compliance queries
        // can filter by data class.
        const dataClass = actionSpec.isKnowledgeBase
            ? 'KNOWLEDGE_BASE'
            : 'ACTION_GROUP';
        // -- PHI scan on action arguments -----------------------------------------
        const exfilHit = this.scanArgsForExfiltration(args);
        if (exfilHit) {
            const reason = `Possible PHI/data exfiltration detected in AgentCore action args for ` +
                `"${actionName}" (key: "${exfilHit}"). Blocked at G5/G7 egress guard.`;
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                actionName,
                dataClass,
                exfilHit,
                reason,
            });
            this.recordFailure();
            return { type: ActionDecisionType.DENY, reason, auditId };
        }
        // -- Sensitive action group REQUIRE_APPROVAL routing ----------------------
        if (this.agentCoreConfig.sensitiveActionGroups.includes(actionSpec.actionGroupName)) {
            const tier = 'human-reviewer';
            const queueId = this.config.reviewerQueues[tier];
            if (!queueId) {
                const reason = `AgentCore action group "${actionSpec.actionGroupName}" is sensitive but ` +
                    'no human-reviewer queue binding exists. Fail closed.';
                this.emitCanonical('orchestrator:task-denied', { agentId, actionName, reason });
                this.recordFailure();
                return { type: ActionDecisionType.DENY, reason, auditId };
            }
            this.emitCanonical('orchestrator:reviewer-routed', {
                agentId,
                actionName,
                dataClass,
                tier,
                queueId,
                layer: 'bedrock-agentcore',
            });
            return {
                type: ActionDecisionType.REQUIRE_APPROVAL,
                reason: `AgentCore action group "${actionSpec.actionGroupName}" requires human-reviewer approval`,
                auditId,
                metadata: {
                    reviewerTier: tier,
                    layer: 'bedrock-agentcore',
                    agentId,
                    actionName,
                    dataClass,
                },
            };
        }
        // -- Approve ---------------------------------------------------------------
        this.emitCanonical('orchestrator:task-approved', {
            agentId,
            actionName,
            dataClass,
            callCount,
            layer: 'bedrock-agentcore',
        });
        return {
            type: ActionDecisionType.ALLOW,
            reason: `AgentCore action "${actionName}" (${dataClass}) approved for agent "${agentId}"`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // toolResult -- post-action audit + Knowledge Base PHI classifier
    // ---------------------------------------------------------------------------
    /**
     * Called after every AgentCore action group or Knowledge Base result returns.
     * For Knowledge Base retrievals, applies PHI classifier to retrieved passages.
     * Emits audit event with data class tag for compliance queries.
     */
    async toolResult(agentId, actionSpec, result) {
        this.assertInitialized();
        const actionName = `${actionSpec.actionGroupName}.${actionSpec.operationName}`;
        const dataClass = actionSpec.isKnowledgeBase
            ? 'KNOWLEDGE_BASE'
            : 'ACTION_GROUP';
        const outputString = typeof result.output === 'string'
            ? result.output
            : JSON.stringify(result.output ?? '');
        const hasSuspiciousOutput = this.containsPhiPattern(outputString);
        this.emitCanonical('orchestrator:plan-step-end', {
            agentId,
            actionName,
            dataClass,
            success: result.success,
            durationMs: result.durationMs ?? null,
            suspiciousOutput: hasSuspiciousOutput,
            layer: 'bedrock-agentcore',
        });
        // For Knowledge Base retrievals, PHI in results is particularly high-risk.
        if (hasSuspiciousOutput) {
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                actionName,
                dataClass,
                reason: `Output classifier: possible PHI/PAN in AgentCore ${dataClass} result. ` +
                    'Surfaced to compliance review queue.',
                layer: 'post-action-classifier',
            });
        }
    }
    // ---------------------------------------------------------------------------
    // knowledgeBaseRetrieval -- dedicated KB retrieval governance hook
    // ---------------------------------------------------------------------------
    /**
     * Called specifically for Knowledge Base retrieval operations.
     * KB retrievals are a separate ingress data class from action groups.
     * This hook classifies each retrieved passage for PHI/PII at emit time.
     *
     * PHI found in KB passages emits a BedrockKbPhiError audit event.
     * It does NOT throw (retrieval is post-hoc) but surfaces to compliance review.
     */
    async knowledgeBaseRetrieval(agentId, kbResult) {
        this.assertInitialized();
        // Classify each passage at emit time (not at consumption time)
        const passages = kbResult.retrievedPassages ?? [];
        const phiPassages = [];
        for (let i = 0; i < passages.length; i++) {
            if (this.containsPhiPattern(passages[i].text)) {
                phiPassages.push(i);
            }
        }
        const hasPhiContent = phiPassages.length > 0 || kbResult.hasPotentialPhi === true;
        this.emitCanonical('orchestrator:plan-step-end', {
            agentId,
            knowledgeBaseId: kbResult.knowledgeBaseId,
            dataClass: 'KNOWLEDGE_BASE',
            passageCount: passages.length,
            phiPassageIndices: phiPassages,
            hasPotentialPhi: hasPhiContent,
            layer: 'kb-retrieval-classifier',
        });
        if (hasPhiContent) {
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                knowledgeBaseId: kbResult.knowledgeBaseId,
                dataClass: 'KNOWLEDGE_BASE',
                phiPassageIndices: phiPassages,
                reason: `Knowledge Base retrieval (${kbResult.knowledgeBaseId}) contains possible PHI ` +
                    'in retrieved passages. Classified as KNOWLEDGE_BASE ingress. ' +
                    'Surfaced to HIPAA compliance review.',
                layer: 'kb-phi-classifier',
            });
        }
    }
    // ---------------------------------------------------------------------------
    // llmCall -- pre-model gate
    // ---------------------------------------------------------------------------
    /**
     * Called before every Bedrock foundation model call.
     *   1. Active-agent check
     *   2. Pack-binding presence
     *   3. Approved model ID check
     */
    async llmCall(agentId, modelId, messages, tools) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        // -- Active-agent check ---------------------------------------------------
        if (!this.activeAgents.has(agentId)) {
            const reason = `Bedrock AgentCore agent "${agentId}" called llmCall without agentStart`;
            this.emitCanonical('orchestrator:task-denied', { agentId, modelId, reason });
            this.recordFailure();
            throw new OrchestratorError({
                message: reason,
                code: 'BEDROCK_AGENTCORE_NO_AGENT_START',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Pack-binding check ---------------------------------------------------
        const snapshot = this.activeAgents.get(agentId);
        if (this.agentCoreConfig.enforcePackBinding !== false &&
            (!snapshot.packBinding || snapshot.packBinding.length === 0)) {
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                modelId,
                reason: 'Missing pack binding at Bedrock AgentCore llmCall',
            });
            this.recordFailure();
            throw new BedrockUnboundDataError(agentId, `llmCall(${modelId})`);
        }
        // -- Approved model ID check ----------------------------------------------
        if (!this.agentCoreConfig.approvedModelIds.includes(modelId)) {
            const reason = `Bedrock model "${modelId}" is not on the approved model list for ` +
                `pack binding [${snapshot.packBinding.join(', ')}].`;
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                modelId,
                packBinding: snapshot.packBinding,
                approvedModelIds: this.agentCoreConfig.approvedModelIds,
                reason,
            });
            this.recordFailure();
            throw new OrchestratorError({
                message: reason,
                code: 'BEDROCK_AGENTCORE_UNAPPROVED_MODEL',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        // -- Approve LLM call -----------------------------------------------------
        this.emitCanonical('orchestrator:plan-step-begin', {
            agentId,
            modelId,
            region: snapshot.region,
            messageCount: messages.length,
            toolCount: tools.length,
            packBinding: snapshot.packBinding,
            layer: 'bedrock-agentcore',
        });
        return {
            type: ActionDecisionType.ALLOW,
            reason: `Bedrock model "${modelId}" approved for AgentCore agent "${agentId}"`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // llmResult -- post-model output scan
    // ---------------------------------------------------------------------------
    /**
     * Called after the Bedrock model response arrives.
     * Scans response content for PHI/PAN exfiltration patterns.
     */
    async llmResult(agentId, modelId, response) {
        this.assertInitialized();
        const responseText = (response.output ?? [])
            .map((b) => (typeof b.text === 'string' ? b.text : ''))
            .join(' ');
        const hasExfil = this.containsPhiPattern(responseText);
        this.emitCanonical('orchestrator:plan-step-end', {
            agentId,
            modelId,
            stopReason: response.stopReason ?? null,
            inputTokens: response.usage?.inputTokens ?? null,
            outputTokens: response.usage?.outputTokens ?? null,
            outputExfiltrationFlag: hasExfil,
            layer: 'llm-result',
        });
        if (hasExfil) {
            this.emitCanonical('orchestrator:task-denied', {
                agentId,
                modelId,
                reason: 'Output exfiltration scanner: possible PHI/PAN in Bedrock model response. ' +
                    'Flagged for compliance review.',
                layer: 'post-llm-classifier',
            });
        }
    }
    // ---------------------------------------------------------------------------
    // agentEnd -- terminal audit event sealing
    // ---------------------------------------------------------------------------
    /**
     * Called when a Bedrock AgentCore run terminates (success or failure).
     * Seals the terminal audit event and cleans up tracking state.
     */
    async agentEnd(agentId, sessionId, outcome) {
        this.assertInitialized();
        const snapshot = this.activeAgents.get(agentId);
        const actionCallCount = this.actionCallCounters.get(agentId) ?? 0;
        this.emitCanonical('orchestrator:workflow-complete', {
            agentId,
            sessionId,
            success: outcome.success,
            summary: outcome.summary ?? (outcome.success ? 'AgentCore run complete' : 'AgentCore run failed'),
            durationMs: outcome.durationMs ?? null,
            error: outcome.error ?? null,
            actionCallCount,
            packBinding: snapshot?.packBinding ?? [],
            modelId: snapshot?.modelId ?? null,
            region: snapshot?.region ?? null,
        });
        // Clean up agent tracking
        this.activeAgents.delete(agentId);
        this.actionCallCounters.delete(agentId);
        if (outcome.success) {
            this.recordSuccess();
        }
        else {
            this.recordFailure();
        }
    }
    // ---------------------------------------------------------------------------
    // Private helpers
    // ---------------------------------------------------------------------------
    /**
     * Scan action arguments for potential exfiltration patterns.
     */
    scanArgsForExfiltration(args) {
        for (const key of this.agentCoreConfig.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: 'Bedrock AgentCore 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
    // ---------------------------------------------------------------------------
    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: ActionDecisionType.DENY, reason, auditId };
        }
        this.emitCanonical('orchestrator:task-approved', {
            taskId: task.taskId,
            agentName: task.assignedAgent.name,
        });
        return {
            type: ActionDecisionType.ALLOW,
            reason: `Task "${task.taskId}" approved via BedrockAgentCoreAdapter`,
            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: ActionDecisionType.DENY, reason, auditId };
        }
        this.emitCanonical('orchestrator:plan-approved', { planId: plan.planId });
        return { type: 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.agentCoreConfig.sensitiveActionGroups.includes(p));
        if (restricted.length > 0) {
            const reason = `AgentCore delegation includes restricted action groups: ${restricted.join(', ')}`;
            this.emitCanonical('orchestrator:delegation-denied', {
                delegationId: d.delegationId,
                from: d.fromAgent.name,
                to: d.toAgent.name,
                restricted,
            });
            return {
                type: ActionDecisionType.DENY,
                reason,
                restrictedPermissions: restricted,
                auditId,
            };
        }
        this.emitCanonical('orchestrator:delegation-approved', {
            delegationId: d.delegationId,
            from: d.fromAgent.name,
            to: d.toAgent.name,
        });
        return { type: 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: 'Bedrock AgentCore role edge permitted', auditId };
    }
    // ---------------------------------------------------------------------------
    // Error translation
    // ---------------------------------------------------------------------------
    translateError(raw) {
        if (raw instanceof OrchestratorError)
            return raw;
        const message = raw instanceof Error ? raw.message : String(raw);
        if (message.includes('BedrockBaaRegionError') || message.includes('BAA-covered Bedrock')) {
            return new OrchestratorError({
                message: `Bedrock AgentCore BAA region violation: ${message}`,
                code: 'BEDROCK_AGENTCORE_BAA_REGION_VIOLATION',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        if (message.includes('BedrockUnboundDataError') || message.includes('pack binding')) {
            return new OrchestratorError({
                message: `Bedrock AgentCore unbound data: ${message}`,
                code: 'BEDROCK_AGENTCORE_UNBOUND_DATA',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        if (message.includes('BEDROCK_AGENTCORE_UNAPPROVED_MODEL')) {
            return new OrchestratorError({
                message: `Bedrock AgentCore unapproved model: ${message}`,
                code: 'BEDROCK_AGENTCORE_UNAPPROVED_MODEL',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        return new OrchestratorError({
            message,
            code: 'BEDROCK_AGENTCORE_ERROR',
            orchestratorId: this.orchestratorId,
            adapterId: this.adapterId,
            raw,
        });
    }
    // ---------------------------------------------------------------------------
    // Capabilities
    // ---------------------------------------------------------------------------
    getOrchestratorCapabilities() {
        return {
            workflowGovernance: true,
            taskGovernance: true,
            planGovernance: true,
            delegationGovernance: true,
            roleEdgeGovernance: true,
            parallelExecution: true,
            nestedPlans: false, // AgentCore does not natively support nested plan trees
            circuitBreaker: true,
        };
    }
}
//# sourceMappingURL=bedrock-agentcore.js.map