"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteVariableToolDefinition = exports.listVariablesToolDefinition = exports.storeToolCallToVariableDefinition = exports.getVariableToolDefinition = exports.setVariableToolDefinition = exports.CustomVariables = void 0;
class CustomVariables {
    toolsService;
    variables = {};
    setVariableToolName = "setVariable";
    getVariableToolName = "getVariable";
    storeToolCallToolName = "storeToolCallToVariable";
    listVariablesToolName = "listVariables";
    deleteVariableToolName = "deleteVariable";
    constructor(toolsService) {
        this.toolsService = toolsService;
        this.registerTools(toolsService);
    }
    isValidVariableName(name) {
        return /^[a-zA-Z0-9_]+$/.test(name);
    }
    setVariable(name, contents) {
        if (!this.isValidVariableName(name)) {
            return `Error: Invalid variable name "${name}". Only alphanumeric characters and underscores are allowed.`;
        }
        this.variables[name] = contents;
        return `Variable "${name}" has been set successfully.`;
    }
    getVariable(varName) {
        if (!this.isValidVariableName(varName)) {
            return `Error: Invalid variable name "${varName}". Only alphanumeric characters and underscores are allowed.`;
        }
        if (!(varName in this.variables)) {
            return `Error: Variable "${varName}" is not defined. Available variables: ${Object.keys(this.variables).join(", ")}`;
        }
        const value = this.variables[varName];
        if (typeof value === "string") {
            return value;
        }
        return JSON.stringify(value, null, 2);
    }
    async storeToolCallToVariable(varName, toolName, toolArgs) {
        if (!this.isValidVariableName(varName)) {
            return `Error: Invalid variable name "${varName}". Only alphanumeric characters and underscores are allowed.`;
        }
        try {
            let parsedArgs;
            try {
                parsedArgs = JSON.parse(toolArgs);
            }
            catch {
                return `Error: Invalid JSON in toolArgs parameter: ${toolArgs}`;
            }
            const result = await this.toolsService.callTool({
                id: `${toolName}-${Date.now()}`,
                type: "function",
                function: {
                    name: toolName,
                    arguments: parsedArgs,
                },
            });
            this.variables[varName] = result;
            return `Tool call result for "${toolName}" has been stored in variable "${varName}".`;
        }
        catch (error) {
            return `Error storing tool call result: ${error.message}`;
        }
    }
    listVariables() {
        const variableNames = Object.keys(this.variables);
        if (variableNames.length === 0) {
            return "No variables are currently stored.";
        }
        const variableList = variableNames
            .map((name) => {
            const value = this.variables[name];
            const preview = typeof value === "string"
                ? value.length > 50
                    ? value.substring(0, 50) + "..."
                    : value
                : JSON.stringify(value).substring(0, 50) +
                    (JSON.stringify(value).length > 50 ? "..." : "");
            return `- ${name}: ${preview}`;
        })
            .join("\n");
        return `Currently stored variables (${variableNames.length}):\n${variableList}`;
    }
    deleteVariable(varName) {
        if (!this.isValidVariableName(varName)) {
            return `Error: Invalid variable name "${varName}". Only alphanumeric characters and underscores are allowed.`;
        }
        if (!(varName in this.variables)) {
            return `Error: Variable "${varName}" is not defined. Available variables: ${Object.keys(this.variables).join(", ")}`;
        }
        delete this.variables[varName];
        return `Variable "${varName}" has been deleted successfully.`;
    }
    substituteVariables(value, processedVars = new Set()) {
        if (typeof value === "string") {
            return value.replace(/\{\{([a-zA-Z0-9_]+)\}\}/g, (match, varName) => {
                if (processedVars.has(varName)) {
                    return match;
                }
                if (!(varName in this.variables)) {
                    return match;
                }
                const varValue = this.variables[varName];
                if (typeof varValue === "string") {
                    return varValue;
                }
                return JSON.stringify(varValue);
            });
        }
        if (Array.isArray(value)) {
            return value.map((item) => this.substituteVariables(item, processedVars));
        }
        if (value && typeof value === "object") {
            const result = {};
            for (const [key, val] of Object.entries(value)) {
                result[key] = this.substituteVariables(val, processedVars);
            }
            return result;
        }
        return value;
    }
    processMessage(message) {
        const processedMessage = { ...message };
        if (typeof processedMessage.content === "string") {
            processedMessage.content = this.substituteVariables(processedMessage.content);
        }
        if (processedMessage.tool_calls) {
            processedMessage.tool_calls = processedMessage.tool_calls.map((toolCall) => ({
                ...toolCall,
                function: {
                    ...toolCall.function,
                    arguments: this.substituteVariables(toolCall.function.arguments),
                },
            }));
        }
        return processedMessage;
    }
    createProcessor(filterFn) {
        return async (originalMessages, modifiedMessages) => {
            for (let i = 0; i < modifiedMessages.length; i++) {
                const message = modifiedMessages[i];
                if (filterFn && !filterFn(message)) {
                    continue;
                }
                modifiedMessages[i] = this.processMessage(message);
            }
        };
    }
    registerTools(toolsService) {
        toolsService.addTools([
            exports.setVariableToolDefinition,
            exports.getVariableToolDefinition,
            exports.storeToolCallToVariableDefinition,
            exports.listVariablesToolDefinition,
            exports.deleteVariableToolDefinition,
        ]);
        toolsService.addFunctions({
            [this.setVariableToolName]: (name, contents) => {
                return this.setVariable(name, contents);
            },
            [this.getVariableToolName]: (varName) => {
                return this.getVariable(varName);
            },
            [this.storeToolCallToolName]: async (varName, toolName, toolArgs) => {
                return await this.storeToolCallToVariable(varName, toolName, toolArgs);
            },
            [this.listVariablesToolName]: () => {
                return this.listVariables();
            },
            [this.deleteVariableToolName]: (varName) => {
                return this.deleteVariable(varName);
            },
        });
    }
    getVariableNames() {
        return Object.keys(this.variables);
    }
    clearVariables() {
        this.variables = {};
    }
    getVariableCount() {
        return Object.keys(this.variables).length;
    }
}
exports.CustomVariables = CustomVariables;
exports.setVariableToolDefinition = {
    type: "function",
    function: {
        name: "setVariable",
        description: "Store a value in a variable for later use. The variable can then be referenced using {{variableName}} syntax in messages or tool calls.",
        parameters: {
            type: "object",
            positional: true,
            properties: {
                name: {
                    type: "string",
                    description: "The name of the variable (alphanumeric and underscore only)",
                },
                contents: {
                    type: "string",
                    description: "The value to store in the variable",
                },
            },
            required: ["name", "contents"],
        },
    },
};
exports.getVariableToolDefinition = {
    type: "function",
    function: {
        name: "getVariable",
        description: "Retrieve the value of a previously stored variable.",
        parameters: {
            type: "object",
            positional: true,
            properties: {
                varName: {
                    type: "string",
                    description: "The name of the variable to retrieve",
                },
            },
            required: ["varName"],
        },
    },
};
exports.storeToolCallToVariableDefinition = {
    type: "function",
    function: {
        name: "storeToolCallToVariable",
        description: "Execute a tool call and store its result in a variable for later use.",
        parameters: {
            type: "object",
            positional: true,
            properties: {
                varName: {
                    type: "string",
                    description: "The name of the variable to store the result in",
                },
                toolName: {
                    type: "string",
                    description: "The name of the tool to call",
                },
                toolArgs: {
                    type: "string",
                    description: "The arguments for the tool call as a JSON string",
                },
            },
            required: ["varName", "toolName", "toolArgs"],
        },
    },
};
exports.listVariablesToolDefinition = {
    type: "function",
    function: {
        name: "listVariables",
        description: "List all currently stored variables with their values.",
        parameters: {
            type: "object",
            positional: false,
            properties: {},
            required: [],
        },
    },
};
exports.deleteVariableToolDefinition = {
    type: "function",
    function: {
        name: "deleteVariable",
        description: "Delete a specific variable from storage.",
        parameters: {
            type: "object",
            positional: true,
            properties: {
                varName: {
                    type: "string",
                    description: "The name of the variable to delete",
                },
            },
            required: ["varName"],
        },
    },
};
//# sourceMappingURL=CustomVariables.js.map