"use strict";
/**
 * AutoGenAdapter -- Orchestrator adapter for Microsoft AutoGen v0.4.
 *
 * Hook surface: AutoGen v0.4 AgentRuntime message interceptor. The adapter
 * exposes a toMessageInterceptor() method returning an interceptor object
 * that customers register with AgentRuntime:
 *
 *   const adapter = new AutoGenAdapter(config);
 *   adapter.initialize(orchConfig);
 *   const interceptor = adapter.toMessageInterceptor();
 *   runtime.addInterceptor(interceptor);
 *
 * Group-chat governance: each GroupChatManager.step() call maps to a plan
 * step. The adapter emits orchestrator:plan-step-begin and
 * orchestrator:plan-step-end around each step.
 *
 * Termination auditing: when a group chat terminates via speaker-selection
 * exhaustion (no speaker found), the adapter emits
 * orchestrator:termination-by-exhaustion WARN so operators can identify
 * runaway loops.
 *
 * Function-call governance: agent function calls are pre-approved before the
 * LLM dispatches the tool. This is distinct from the LLM provider adapter
 * which fires at the model call level.
 *
 * DEFERRED-AUTOGEN-V04-API: Verify that the AgentRuntime interceptor surface
 * fires before LLM dispatch (not after) at implementation time. The v0.4
 * interceptor API changed from the v0.2 middleware pattern. If the intercept
 * fires after LLM dispatch, the governance check must be restructured.
 *
 * No live AutoGen SDK installed. All framework surfaces are shims.
 * Tests use fake interceptor dispatch with in-process fakes only.
 *
 * Spec: P3-ORCH-01, Section 2.4, AC 8-9
 * @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.AutoGenAdapter = exports.AutoGenMessageInterceptor = void 0;
const crypto = __importStar(require("crypto"));
const base_1 = require("./base");
const index_1 = require("./index");
const index_2 = require("../adapters/index");
// ---------------------------------------------------------------------------
// AutoGenMessageInterceptor -- shimmed interceptor object
// ---------------------------------------------------------------------------
/**
 * Interceptor object returned by AutoGenAdapter.toMessageInterceptor().
 *
 * Customers register it with AgentRuntime:
 *   runtime.addInterceptor(interceptor);
 *
 * DEFERRED-AUTOGEN-V04-API: The exact registration method name
 * (addInterceptor vs registerMiddleware vs addHook) must be confirmed
 * against the v0.4 release. The method names on this shim are illustrative.
 */
class AutoGenMessageInterceptor {
    adapter;
    constructor(adapter) {
        this.adapter = adapter;
    }
    /**
     * Called before a message is delivered to the recipient agent.
     * Governance check; returns false to block the message.
     */
    async beforeMessage(message) {
        return this.adapter.handleMessageBefore(message);
    }
    /**
     * Called after a message is delivered.
     * Audit hook.
     */
    async afterMessage(message) {
        return this.adapter.handleMessageAfter(message);
    }
    /**
     * Called before a function/tool invocation.
     * Governance check; throws OrchestratorError to block the call.
     */
    async beforeFunctionCall(call) {
        return this.adapter.handleFunctionCallBefore(call);
    }
    /**
     * Called when a GroupChatManager step begins.
     * Emits orchestrator:plan-step-begin.
     */
    async onGroupChatStepBegin(step) {
        return this.adapter.handleGroupChatStepBegin(step);
    }
    /**
     * Called when a GroupChatManager step ends.
     * Emits orchestrator:plan-step-end. When speakerExhausted is true,
     * also emits orchestrator:termination-by-exhaustion WARN.
     */
    async onGroupChatStepEnd(step) {
        return this.adapter.handleGroupChatStepEnd(step);
    }
    /**
     * Called when an agent-to-agent routing event occurs.
     * Maps onto the DelegationDecision contract.
     */
    async onRouting(event) {
        return this.adapter.handleRouting(event);
    }
}
exports.AutoGenMessageInterceptor = AutoGenMessageInterceptor;
// ---------------------------------------------------------------------------
// AutoGenAdapter
// ---------------------------------------------------------------------------
class AutoGenAdapter extends base_1.BaseOrchestratorAdapter {
    adapterId = 'autogen';
    orchestratorId = 'autogen';
    autogenConfig;
    /** Track step counts per session for max-steps enforcement. */
    sessionStepCounts = new Map();
    constructor(config) {
        super();
        this.autogenConfig = config;
    }
    // ---------------------------------------------------------------------------
    // toMessageInterceptor -- public factory
    // ---------------------------------------------------------------------------
    /**
     * Return an AutoGenMessageInterceptor wired to this adapter.
     * Customers register the returned interceptor with AgentRuntime.
     */
    toMessageInterceptor() {
        this.assertInitialized();
        return new AutoGenMessageInterceptor(this);
    }
    // ---------------------------------------------------------------------------
    // Internal interceptor dispatchers
    // ---------------------------------------------------------------------------
    /**
     * Governance check before a message is delivered.
     * Checks the sender against the allowed agent list and circuit breaker.
     */
    async handleMessageBefore(message) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        if (this.isCircuitOpen()) {
            const reason = 'Circuit breaker is open; message blocked';
            this.emitCanonical('orchestrator:task-denied', {
                messageId: message.messageId,
                sender: message.sender,
                reason,
            });
            this.recordFailure();
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        if (!this.autogenConfig.allowedAgents.includes(message.sender)) {
            const reason = `Agent "${message.sender}" is not in the allowed agent list`;
            this.emitCanonical('orchestrator:task-denied', {
                messageId: message.messageId,
                sender: message.sender,
                reason,
            });
            this.recordFailure();
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        this.emitCanonical('orchestrator:task-approved', {
            messageId: message.messageId,
            sender: message.sender,
            recipient: message.recipient,
            messageType: message.messageType,
        });
        this.recordSuccess();
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `Message from "${message.sender}" to "${message.recipient}" approved`,
            auditId,
        };
    }
    /** Audit hook after a message is delivered. */
    async handleMessageAfter(message) {
        this.assertInitialized();
        this.emitCanonical('orchestrator:plan-step-end', {
            messageId: message.messageId,
            sender: message.sender,
            recipient: message.recipient,
        });
    }
    /**
     * Governance check before a function/tool call.
     * Sensitive functions are routed to the human-reviewer tier.
     */
    async handleFunctionCallBefore(call) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        const isSensitive = this.autogenConfig.sensitiveFunctions.includes(call.functionName);
        if (isSensitive) {
            const tier = 'human-reviewer';
            const queueId = this.config.reviewerQueues[tier];
            if (!queueId) {
                const reason = `Function "${call.functionName}" is sensitive but no human-reviewer queue binding exists`;
                this.emitCanonical('orchestrator:task-denied', {
                    callId: call.callId,
                    functionName: call.functionName,
                    reason,
                });
                return { type: index_2.ActionDecisionType.DENY, reason, auditId };
            }
            this.emitCanonical('orchestrator:reviewer-routed', {
                callId: call.callId,
                functionName: call.functionName,
                tier,
                queueId,
            });
            return {
                type: index_2.ActionDecisionType.REQUIRE_APPROVAL,
                reason: `Function "${call.functionName}" is sensitive; routing to ${tier}`,
                auditId,
                metadata: { reviewerTier: tier, functionName: call.functionName },
            };
        }
        this.emitCanonical('orchestrator:task-approved', {
            callId: call.callId,
            functionName: call.functionName,
            callerAgent: call.callerAgent,
        });
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `Function "${call.functionName}" approved`,
            auditId,
        };
    }
    /**
     * GroupChatManager step begin.
     * Emits orchestrator:plan-step-begin.
     * Enforces max-step limit.
     */
    async handleGroupChatStepBegin(step) {
        this.assertInitialized();
        const current = (this.sessionStepCounts.get(step.sessionId) ?? 0) + 1;
        this.sessionStepCounts.set(step.sessionId, current);
        const maxSteps = this.autogenConfig.maxGroupChatSteps;
        if (maxSteps !== undefined && current > maxSteps) {
            this.emitCanonical('orchestrator:termination-by-exhaustion', {
                sessionId: step.sessionId,
                groupName: step.groupName,
                stepIndex: step.stepIndex,
                reason: `Group chat exceeded maxGroupChatSteps (${maxSteps}); treating as exhaustion`,
            });
            throw new index_1.OrchestratorError({
                message: `Group chat session "${step.sessionId}" exceeded the maximum of ${maxSteps} steps.`,
                code: 'AUTOGEN_MAX_STEPS_EXCEEDED',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
            });
        }
        this.emitCanonical('orchestrator:plan-step-begin', {
            sessionId: step.sessionId,
            groupName: step.groupName,
            stepIndex: step.stepIndex,
            selectedSpeaker: step.selectedSpeaker,
        });
    }
    /**
     * GroupChatManager step end.
     * Emits orchestrator:plan-step-end.
     * When speakerExhausted is true, also emits
     * orchestrator:termination-by-exhaustion WARN.
     */
    async handleGroupChatStepEnd(step) {
        this.assertInitialized();
        this.emitCanonical('orchestrator:plan-step-end', {
            sessionId: step.sessionId,
            groupName: step.groupName,
            stepIndex: step.stepIndex,
            messageCount: step.messages.length,
        });
        if (step.speakerExhausted) {
            this.emitCanonical('orchestrator:termination-by-exhaustion', {
                sessionId: step.sessionId,
                groupName: step.groupName,
                stepIndex: step.stepIndex,
                reason: 'Speaker-selection exhausted: no eligible speaker found for this step',
            });
        }
    }
    /**
     * Agent-to-agent routing governance.
     * Maps onto the DelegationDecision contract.
     */
    async handleRouting(event) {
        this.assertInitialized();
        const auditId = crypto.randomUUID();
        const restricted = event.grantedPermissions.filter((p) => this.autogenConfig.sensitiveFunctions.includes(p));
        if (restricted.length > 0) {
            const reason = `Agent routing grants restricted permissions: ${restricted.join(', ')}`;
            this.emitCanonical('orchestrator:delegation-denied', {
                routingId: event.routingId,
                from: event.fromAgent,
                to: event.toAgent,
                restricted,
            });
            return {
                type: index_2.ActionDecisionType.DENY,
                reason,
                restrictedPermissions: restricted,
                auditId,
            };
        }
        this.emitCanonical('orchestrator:delegation-approved', {
            routingId: event.routingId,
            from: event.fromAgent,
            to: event.toAgent,
            grantedPermissions: event.grantedPermissions,
        });
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `Routing from "${event.fromAgent}" to "${event.toAgent}" approved`,
            auditId,
        };
    }
    // ---------------------------------------------------------------------------
    // OrchestratorAdapter surface -- workflow lifecycle
    // ---------------------------------------------------------------------------
    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: 'AutoGen group chat 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,
        });
    }
    // ---------------------------------------------------------------------------
    // 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: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        this.emitCanonical('orchestrator:task-approved', { taskId: task.taskId });
        return {
            type: index_2.ActionDecisionType.ALLOW,
            reason: `Task "${task.taskId}" approved via AutoGenAdapter`,
            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 });
        const maxSteps = this.autogenConfig.maxGroupChatSteps;
        if (maxSteps !== undefined && plan.steps.length > maxSteps) {
            const reason = `Plan has ${plan.steps.length} steps, exceeding the maximum of ${maxSteps}`;
            this.emitCanonical('orchestrator:plan-denied', { planId: plan.planId, reason });
            return { type: index_2.ActionDecisionType.DENY, reason, auditId };
        }
        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.autogenConfig.sensitiveFunctions.includes(p));
        if (restricted.length > 0) {
            const reason = `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: 'AutoGen 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('GroupChatTermination') || message.includes('speaker') ||
            message.includes('exhausted')) {
            return new index_1.OrchestratorError({
                message: `AutoGen group chat terminated: ${message}`,
                code: 'AUTOGEN_GROUP_CHAT_TERMINATION',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        if (message.includes('timeout') || message.includes('Timeout')) {
            return new index_1.OrchestratorError({
                message: `AutoGen runtime timeout: ${message}`,
                code: 'AUTOGEN_TIMEOUT',
                orchestratorId: this.orchestratorId,
                adapterId: this.adapterId,
                raw,
            });
        }
        return new index_1.OrchestratorError({
            message,
            code: 'AUTOGEN_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,
            circuitBreaker: true,
        };
    }
}
exports.AutoGenAdapter = AutoGenAdapter;
//# sourceMappingURL=autogen.js.map