import { uuidv7 } from 'uuidv7';
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Constants
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const MAX_MESSAGE_BYTES = 10_240; // 10KB
const MAX_CONTEXT_ITEMS = 100;
const AGENT_TIMEOUT_MS = 600_000; // 10 minutes
const MAX_RETRIES = 1;
export class MessageSizeError extends Error {
    constructor(size) {
        super(`Message exceeds 10KB limit: ${size} bytes`);
        this.name = 'MessageSizeError';
    }
}
export class AgentTimeoutError extends Error {
    constructor(agentName, stepId) {
        super(`Agent '${agentName}' timed out on step '${stepId}' after ${AGENT_TIMEOUT_MS / 1000}s`);
        this.name = 'AgentTimeoutError';
    }
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Role → Agent mapping
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const STEP_TYPE_TO_ROLE = {
    spec: 'planner',
    review: 'reviewer',
    implement: 'implementer',
    test: 'tester',
    deploy: 'implementer',
};
const ROLE_TO_AGENT = {
    planner: 'architect',
    implementer: 'implementer',
    reviewer: 'security-reviewer',
    tester: 'tester',
    sentinel: 'SecuritySentinel',
};
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// CollaborationProtocol
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
export class CollaborationProtocol {
    messageLog = [];
    handoffLog = [];
    retryCount = new Map();
    assignAgent(step) {
        const role = STEP_TYPE_TO_ROLE[step.type];
        const agentName = ROLE_TO_AGENT[role];
        return {
            stepId: step.id,
            role,
            agentName,
            assignedAt: new Date().toISOString(),
        };
    }
    createMessage(from, to, type, payload, correlationId) {
        const message = {
            id: uuidv7(),
            from,
            to,
            type,
            payload,
            correlationId: correlationId ?? uuidv7(),
            timestamp: new Date().toISOString(),
        };
        this.validateMessageSize(message);
        this.messageLog.push(message);
        return message;
    }
    handoff(from, to, context) {
        const trimmedContext = this.trimContext(context);
        const handoffMessage = this.createMessage(from, to, 'handoff', trimmedContext);
        const result = {
            id: handoffMessage.id,
            from,
            to,
            context: trimmedContext,
            success: true,
            timestamp: new Date().toISOString(),
        };
        this.handoffLog.push(result);
        return result;
    }
    canRetry(stepId) {
        const count = this.retryCount.get(stepId) ?? 0;
        return count < MAX_RETRIES;
    }
    recordRetry(stepId) {
        const count = this.retryCount.get(stepId) ?? 0;
        this.retryCount.set(stepId, count + 1);
    }
    getRetryCount(stepId) {
        return this.retryCount.get(stepId) ?? 0;
    }
    getMessageLog() {
        return this.messageLog;
    }
    getHandoffLog() {
        return this.handoffLog;
    }
    getTimeoutMs() {
        return AGENT_TIMEOUT_MS;
    }
    getMaxMessageBytes() {
        return MAX_MESSAGE_BYTES;
    }
    validateMessageSize(message) {
        const serialized = JSON.stringify(message);
        const byteLength = Buffer.byteLength(serialized, 'utf-8');
        if (byteLength > MAX_MESSAGE_BYTES) {
            throw new MessageSizeError(byteLength);
        }
    }
    trimContext(context) {
        return {
            files: context.files.slice(0, MAX_CONTEXT_ITEMS),
            changes: context.changes.slice(0, MAX_CONTEXT_ITEMS),
            decisions: context.decisions.slice(0, MAX_CONTEXT_ITEMS),
            metadata: context.metadata,
        };
    }
}
//# sourceMappingURL=CollaborationProtocol.js.map