"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.globalHarmonyToolProcessor = exports.HarmonyToolProcessor = void 0;
class HarmonyToolProcessor {
    static instance;
    static getInstance() {
        if (!HarmonyToolProcessor.instance) {
            HarmonyToolProcessor.instance = new HarmonyToolProcessor();
        }
        return HarmonyToolProcessor.instance;
    }
    detectHarmonyToolCalls(content) {
        const toolCalls = [];
        const harmonyPattern = /<\|channel\|>commentary\s+to=functions\.([a-zA-Z_][a-zA-Z0-9_]*)\s*<\|constrain\|>json<\|message\|>([\s\S]*?)(?=<\|(?!message\|)|$)/g;
        let match;
        while ((match = harmonyPattern.exec(content)) !== null) {
            const [fullMatch, toolName, potentialJson] = match;
            const jsonArgs = this.extractJsonFromContent(potentialJson.trim());
            if (toolName && jsonArgs) {
                toolCalls.push({
                    toolName: toolName.trim(),
                    arguments: jsonArgs,
                    fullMatch,
                });
            }
        }
        return toolCalls;
    }
    detectHarmonyFinalCalls(content) {
        const toolCalls = [];
        const finalChannelPattern = /<\|channel\|>final<\|message\|>([\s\S]*?)(?=<\||$)/g;
        let match;
        while ((match = finalChannelPattern.exec(content)) !== null) {
            const [fullMatch, messageContent] = match;
            toolCalls.push({
                toolName: "finalAnswer",
                arguments: JSON.stringify({ answer: messageContent.trim() }),
                fullMatch,
            });
        }
        const finalTokenPattern = /<\|final\|>([\s\S]*?)(?=<\||$)/g;
        while ((match = finalTokenPattern.exec(content)) !== null) {
            const [fullMatch, messageContent] = match;
            toolCalls.push({
                toolName: "finalAnswer",
                arguments: JSON.stringify({ answer: messageContent.trim() || "Done" }),
                fullMatch,
            });
        }
        return toolCalls;
    }
    extractJsonFromContent(content) {
        const jsonMatch = content.match(/(\{[\s\S]*\})/);
        if (jsonMatch) {
            const jsonCandidate = jsonMatch[1].trim();
            try {
                JSON.parse(jsonCandidate);
                return jsonCandidate;
            }
            catch (error) {
                return null;
            }
        }
        return null;
    }
    validateAndCleanArguments(jsonString) {
        try {
            const parsed = JSON.parse(jsonString);
            return JSON.stringify(parsed);
        }
        catch (error) {
            try {
                let cleaned = jsonString.replace(/,(\s*[}\]])/g, "$1");
                cleaned = cleaned.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
                const parsed = JSON.parse(cleaned);
                return JSON.stringify(parsed);
            }
            catch (secondError) {
                return JSON.stringify({ input: jsonString });
            }
        }
    }
    generateToolCallId() {
        return `harmony_call_${Date.now()}_${Math.random()
            .toString(36)
            .substr(2, 9)}`;
    }
    convertHarmonyToToolCalls(matches) {
        const toolCalls = [];
        for (const match of matches) {
            const { toolName, arguments: jsonArgs } = match;
            if (!toolName)
                continue;
            const toolCall = {
                id: this.generateToolCallId(),
                type: "function",
                function: {
                    name: toolName,
                    arguments: this.validateAndCleanArguments(jsonArgs),
                },
            };
            toolCalls.push(toolCall);
        }
        return toolCalls;
    }
    isHarmonyFormat(content) {
        return ((content.includes("<|channel|>") &&
            content.includes("to=functions.") &&
            content.includes("<|constrain|>json<|message|>")) ||
            content.includes("<|channel|>final<|message|>") ||
            content.includes("<|final|>") ||
            content.includes("<|channel|>finalAnswer<|message|>"));
    }
    processMessage(message) {
        if (message.role !== "assistant") {
            return;
        }
        if (typeof message.content !== "string") {
            return;
        }
        if (message?.tool_calls?.length) {
            return;
        }
        if (!this.isHarmonyFormat(message.content)) {
            return;
        }
        const matches = this.detectHarmonyToolCalls(message.content);
        const finalMatches = this.detectHarmonyFinalCalls(message.content);
        const allMatches = [...matches, ...finalMatches];
        if (allMatches.length === 0) {
            return;
        }
        const toolCalls = this.convertHarmonyToToolCalls(allMatches);
        if (allMatches.length === 0) {
            return;
        }
        if (message.tool_calls) {
            message.tool_calls.push(...toolCalls);
        }
        else {
            message.tool_calls = toolCalls;
        }
    }
    createProcessor() {
        return (originalMessages, modifiedMessages) => {
            for (const message of modifiedMessages) {
                this.processMessage(message);
            }
        };
    }
}
exports.HarmonyToolProcessor = HarmonyToolProcessor;
exports.globalHarmonyToolProcessor = new HarmonyToolProcessor();
//# sourceMappingURL=HarmonyToolProcessor.js.map