groq / groq-typescript

The official Node.js / Typescript library for the Groq API
Apache License 2.0
146 stars 18 forks source link

BadRequestError: 400 for tool uses #103

Open Firegodbr opened 1 month ago

Firegodbr commented 1 month ago

I'm trying to make that Llama 3 can do through Google however I keep getting different errors: One is the Bad request 400: BadRequestError: 400 {"error":{"message":"Failed to call a function. Please adjust your prompt. See 'failed_generation' for more details.","type":"invalid_request_error","code":"tool_use_failed","failed_generation":"<tool-use>\n{\n \"tool_calls\": [\n {\n \"id\": \"pending\",\n \"type\": \"function\",\n \"function\": {\n \"name\": \"get_info\"\n },\n \"parameters\": {\n \"query\": \"current president of the US\"\n }\n }\n ]\n}\n</tool-use>"}} And it looks like it works I get another type of error, the tool is being called with no parameters.

My tool and it's definition:

async function searchOnWeb(search) {
    console.log(search);
    const response = await axios.get(
        "https://www.googleapis.com/customsearch/v1?key=<key>&cx=<cx>" +
            search
    );
    const responseModel = {
        title: response.data["items"][0].title,
        description:
            response.data["items"][0]["pagemap"]["metatags"][
                "og:description"
            ] ?? response.data["items"][0]["snippet"],
        url: response.data["items"][0].link,
    };
    console.log(response.data["items"][0]);
    console.log(responseModel);
    return JSON.stringify(responseModel);
}
const tools = [
    {
        type: "function",
        function: {
            name: "searchOnWeb",
            description:
                "Returns title, url and a description of the first website on web search",
            parameters: {
                type: "object",
                properties: {
                    search: {
                        type: "string",
                        description: "String to search on the web",
                    },
                },
                required: ["search"],
            },
        },
    },
];

My code for chat completion:

const Groq = await import("groq-sdk").then((mod) => mod.Groq);
            const groq = new Groq({
                apiKey: process.env.GROQ_API_KEY,
            });
            console.log("start");
            try {
                const completion = await groq.chat.completions.create({
                    messages: [
                        {
                            role: "system",
                            content:
                                system_prompt ?? "You are a helpful assistant.",
                        },
                        ...Array.from(messages).map((el) => {
                            const role = el.role;
                            if (role === "User") el.role = "user";
                            else if (role === "Assistant")
                                el.role = "assistant";
                            return el;
                        }),
                    ],
                    tools: tools,
                    tool_choice: "auto",
                    model: model_Id,
                    max_tokens: max_new_tokens,
                });
                console.log("start 1");
                const responseMessage = completion.choices[0].message;
                const toolCalls = responseMessage.tool_calls;
                console.log("start 2");
                if (toolCalls) {
                    const availableFunctions = {
                        // calculate: calculate,
                        searchOnWeb: searchOnWeb,
                        // get_weather: get_weather,
                    };

                    messages.push(responseMessage);
                    console.log("first");
                    for (const toolCall of toolCalls) {
                        const functionName = toolCall.function.name;
                        const functionToCall = availableFunctions[functionName];
                        const functionArgs = JSON.parse(
                            toolCall.function.arguments
                        );
                        console.log("first 1");
                        console.log(toolCall);
                        const functionResponse = await functionToCall(
                            functionArgs.expression
                        );
                        console.log("first 2");

                        messages.push({
                            tool_call_id: toolCall.id,
                            role: "tool",
                            name: functionName,
                            content: functionResponse,
                        });
                    }
                    console.log("first 3");
                    const secondResponse = await groq.chat.completions.create({
                        model: model_Id,
                        messages: messages,
                    });
                    response = secondResponse.choices[0].message.content;
                } else response = responseMessage.content;
            } catch (error) {
                console.log(error);
                response = error.failed_generation;
            }

What's causing this errors?