All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xyz.felh.openai.jtokkit.utils.FunctionFormat Maven / Gradle / Ivy

The newest version!
package xyz.felh.openai.jtokkit.utils;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import xyz.felh.openai.chat.tool.Function;
import xyz.felh.openai.chat.tool.Tool;
import xyz.felh.utils.Preconditions;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class FunctionFormat {

    public static String formatFunctionDefinitions(List tools) {
        List lines = new ArrayList<>();
        lines.add("namespace functions {");
        lines.add("");
        for (Tool tool : tools) {
            Function function = tool.getFunction();
            if (Preconditions.isNotBlank(function.getDescription())) {
                lines.add(String.format("// %s", function.getDescription()));
            }
            JSONObject p = JSONObject.parseObject(JSONObject.toJSONString(function.getParameters()));
            JSONObject properties = p.getJSONObject("properties");
            if (Preconditions.isNotBlank(properties) && Preconditions.isNotBlank(properties.keySet())) {
                lines.add(String.format("type %s = (_: {", function.getName()));
                lines.add(formatObjectProperties(p, 0));
                lines.add("}) => any;");
            } else {
                lines.add(String.format("type %s = () => any;", function.getName()));
            }
            lines.add("");
        }
        lines.add("} // namespace functions");
        return String.join("\n", lines);
    }

    private static String formatObjectProperties(JSONObject p, int indent) {
        JSONObject properties = p.getJSONObject("properties");
        if (Preconditions.isBlank(properties)) {
            return "";
        }
        List requiredParams = p.getList("required", String.class);
        List lines = new ArrayList<>();
        for (String key : properties.keySet()) {
            JSONObject props = properties.getJSONObject(key);
            String description = props.getString("description");
            if (Preconditions.isNotBlank(description)) {
                lines.add(String.format("// %s", description));
            }
            String question = "?";
            if (Preconditions.isNotBlank(requiredParams) && requiredParams.contains(key)) {
                question = "";
            }
            lines.add(String.format("%s%s: %s,", key, question, formatType(props, indent)));
        }

        return lines.stream().map(it -> " ".repeat(Math.max(0, indent)) + it).collect(Collectors.joining("\n"));
    }

    private static String formatType(JSONObject props, int indent) {
        String type = props.getString("type");
        return switch (type) {
            case "string" -> {
                if (props.containsKey("enum")) {
                    yield props.getList("enum", String.class).stream().map(it ->
                            String.format("\"%s\"", it)).collect(Collectors.joining(" | "));
                }
                yield "string";
            }
            case "array" -> {
                if (props.containsKey("items")) {
                    yield String.format("%s[]", formatType(props.getJSONObject("items"), indent));
                }
                yield "any[]";
            }
            case "object" -> String.format("{\n%s\n}", formatObjectProperties(props, indent + 2));
            case "integer", "number" -> {
                if (props.containsKey("enum")) {
                    yield String.join(" | ", props.getList("enum", String.class).stream().map(it ->
                            String.format("\"%s\"", it)).toList());
                }
                yield "number";
            }
            case "boolean" -> "boolean";
            case "null" -> "null";
            default -> "";
        };
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy