import { compareCodepoints, stableJsonStringify, } from "./stable-json.js";
export function toToolPrefixSpec(definition) {
    return {
        name: definition.name,
        description: definition.description,
        parameters: definition.parameters,
        readOnly: definition.readOnly === true,
        parallelSafe: definition.parallelSafe === true,
        stormExempt: definition.stormExempt === true,
        skipRetentionSave: definition.skipRetentionSave === true,
    };
}
export function sortToolPrefixSpecs(specs) {
    return [...specs].sort((left, right) => {
        const byName = compareCodepoints(left.name, right.name);
        if (byName !== 0)
            return byName;
        return compareCodepoints(stableJsonStringify(left), stableJsonStringify(right));
    });
}
export function toSortedToolPrefixSpecs(definitions) {
    return sortToolPrefixSpecs(definitions.map((definition) => toToolPrefixSpec(definition)));
}
export function isToolReadOnly(definition, args) {
    if (definition.readOnlyCheck)
        return definition.readOnlyCheck(args);
    return definition.readOnly === true;
}
export function createToolExecutionBatches(calls, registry) {
    const batches = [];
    let parallelCalls = [];
    const flushParallel = () => {
        if (parallelCalls.length === 0)
            return;
        batches.push({ kind: "parallel", calls: parallelCalls });
        parallelCalls = [];
    };
    for (const call of calls) {
        const definition = registry.get(call.toolName);
        const canRunInParallel = definition !== undefined &&
            definition.parallelSafe === true &&
            isToolReadOnly(definition, call.args);
        if (canRunInParallel) {
            parallelCalls.push(call);
            continue;
        }
        flushParallel();
        batches.push({ kind: "serial", calls: [call] });
    }
    flushParallel();
    return batches;
}
