Skip to content

feat: support Functionary new chat format #299

@physimo

Description

@physimo

Issue description

Function calling using functionary model doesn't work as the model is using a different token than usual.

Expected Behavior

I tried asking the model to use one function I added on functions:

The function

const evalJavaScript = csmf({
    description: "Evaluate a JavaScript code.",
    params: {
        type: "object",
        properties: {
            code: {
                type: "string",
                description: "JavaScript code to evaluate."
            }
        }
    },
    handler(params: any) {
        console.log("[evalJavaScript called]");
        console.log(params);

        try {
            const hrStart = process.hrtime();
            const lastResult = eval(params.code);
            const hrDiff = process.hrtime(hrStart);
            return { error: false, execution_time: `${hrDiff[0] > 0 ? `${hrDiff[0]}s ` : ''}${hrDiff[1] / 1000000}ms`, result: lastResult }
        }
        catch (err) {
            return { error: true, reason: err }
        }
    }
})

chat_functions['evalJavaScript'] = evalJavaScript;

The prompt

Can you try evaluating this javascript code?

Math.round(Math.random() * 100)

The expected behavior would be the model calling the function, which evaluates the given JavaScript code, which returns a random number to the model

Actual Behavior

The model tried to call the function with given parameters, but failed to do so since apparently it tries to call the function in peculiar way.

This is the actual given response from the model:

Sure, I can do that. Let's evaluate the JavaScript code `Math.round(Math.random() * 100)`.>>>evalJavaScript({"code": "Math.round(Math.random() * 100)"})

image

Steps to reproduce

Using template from npm create --yes node-llama-cpp@beta
And using functionary model small v3.2

import { fileURLToPath } from "url";
import path from "path";
import chalk from "chalk";
import { getLlama, LlamaChatSession, ChatSessionModelFunction, defineChatSessionFunction } from "node-llama-cpp";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const modelsFolderDirectory = path.join(__dirname, "..", "models");
const chat_functions: { [function_name: string]: ChatSessionModelFunction<any> } = {};
const evalJavaScript = defineChatSessionFunction({
    description: "Evaluate a JavaScript code.",
    params: {
        type: "object",
        properties: {
            code: {
                type: "string",
                description: "JavaScript code to evaluate."
            }
        }
    },
    handler(params: any) {
        console.log("[evalJavaScript called]");
        console.log(params);

        try {
            const hrStart = process.hrtime();
            const lastResult = eval(params.code);
            const hrDiff = process.hrtime(hrStart);
            return { error: false, execution_time: `${hrDiff[0] > 0 ? `${hrDiff[0]}s ` : ''}${hrDiff[1] / 1000000}ms`, result: lastResult }
        }
        catch (err) {
            return { error: true, reason: err }
        }
    }
})
chat_functions['evalJavaScript'] = evalJavaScript;

const llama = await getLlama();

console.log(chalk.yellow("Loading model..."));
const model = await llama.loadModel({
    modelPath: path.join(modelsFolderDirectory, "functionary-small-v3.2.F16.gguf")
});

console.log(chalk.yellow("Creating context..."));
const context = await model.createContext();

const session = new LlamaChatSession({
    contextSequence: context.getSequence()
});
console.log();

const q1 = `
Can you try evaluating this javascript code?

Math.round(Math.random() * 100)`.trim();
console.log(chalk.yellow("User: ") + q1);

process.stdout.write(chalk.yellow("AI: "));
const a1 = await session.prompt(q1, {
    functions: chat_functions,
    onTextChunk(chunk) {
        // stream the response to the console as it's being generated
        process.stdout.write(chunk);
    }
});
process.stdout.write("\n");
console.log(chalk.yellow("Consolidated AI answer: ") + a1);
console.log();

process.exit(0);

My Environment

Dependency Version
Operating System Windows 10
CPU Ryzen 3 2200G
GPU RTX 3090
Node.js version 20.10.0
Typescript version 5.4.5
node-llama-cpp version 3.0.0-beta.44

Additional Context

I'm sorry if I was mistaken about this issue, whether this is a bug or my inexperience showing, or whether this is functionary problem or node-llama-cpp problem. I've tried looking at the issues and beta discussion, but none mentioned anything like this so I've had to open this issue.

Relevant Features Used

  • Metal support
  • CUDA support
  • Grammar

Are you willing to resolve this issue by submitting a Pull Request?

No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions