"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    callTool: function() {
        return callTool;
    },
    consumeAsyncIterable: function() {
        return consumeAsyncIterable;
    },
    createReadableStream: function() {
        return createReadableStream;
    }
});
const _env = require("@llamaindex/env");
const _CallbackManager = require("../internal/settings/CallbackManager.js");
const _utils = require("../internal/utils.js");
async function callTool(tool, toolCall, logger) {
    let input;
    if (typeof toolCall.input === "string") {
        try {
            input = JSON.parse(toolCall.input);
        } catch (e) {
            const output = `Tool ${toolCall.name} can't be called. Input is not a valid JSON object.`;
            logger.error(`${output} Try increasing the maxTokens parameter of your LLM. Invalid Input: ${toolCall.input}`);
            return {
                tool,
                input: {},
                output,
                isError: true
            };
        }
    } else {
        input = toolCall.input;
    }
    if (!tool) {
        logger.error(`Tool ${toolCall.name} does not exist.`);
        const output = `Tool ${toolCall.name} does not exist.`;
        return {
            tool,
            input,
            output,
            isError: true
        };
    }
    const call = tool.call;
    let output;
    if (!call) {
        logger.error(`Tool ${tool.metadata.name} (remote:${toolCall.name}) does not have a implementation.`);
        output = `Tool ${tool.metadata.name} (remote:${toolCall.name}) does not have a implementation.`;
        return {
            tool,
            input,
            output,
            isError: true
        };
    }
    try {
        (0, _CallbackManager.getCallbackManager)().dispatchEvent("llm-tool-call", {
            payload: {
                toolCall: {
                    ...toolCall,
                    input
                }
            }
        });
        output = await call.call(tool, input);
        logger.log(`Tool ${tool.metadata.name} (remote:${toolCall.name}) succeeded.`);
        logger.log(`Output: ${JSON.stringify(output)}`);
        const toolOutput = {
            tool,
            input,
            output,
            isError: false
        };
        (0, _CallbackManager.getCallbackManager)().dispatchEvent("llm-tool-result", {
            payload: {
                toolCall: {
                    ...toolCall,
                    input
                },
                toolResult: {
                    ...toolOutput
                }
            }
        });
        return toolOutput;
    } catch (e) {
        output = (0, _utils.prettifyError)(e);
        logger.error(`Tool ${tool.metadata.name} (remote:${toolCall.name}) failed: ${output}`);
    }
    return {
        tool,
        input,
        output,
        isError: true
    };
}
async function consumeAsyncIterable(input, previousContent = "") {
    if ((0, _utils.isAsyncIterable)(input)) {
        const result = {
            content: previousContent,
            // only assistant will give streaming response
            role: "assistant",
            options: {}
        };
        for await (const chunk of input){
            result.content += chunk.delta;
            if (chunk.options) {
                result.options = {
                    ...result.options,
                    ...chunk.options
                };
            }
        }
        return result;
    } else {
        return input;
    }
}
function createReadableStream(asyncIterable) {
    return new _env.ReadableStream({
        async start (controller) {
            for await (const chunk of asyncIterable){
                controller.enqueue(chunk);
            }
            controller.close();
        }
    });
}
