import { UITarsModelVersion } from "@midscene/shared/env";
import { assert } from "@midscene/shared/utils";
import { jsonrepair } from "jsonrepair";
import { extractJSONFromCodeBlock, safeParseJson } from "../../service-caller/json.mjs";
import { unwrapCoordinateListLikeInput } from "../../shared/model-locate-result/index.mjs";
import { uiTarsPlanning } from "./planning.mjs";
const defaultVlmUiTarsReplanningCycleLimit = 40;
function normalizeJsonObject(obj, context = {}) {
    if (null == obj) return obj;
    if (Array.isArray(obj)) return obj.map((item)=>normalizeJsonObject(item, context));
    if ('object' == typeof obj) {
        const normalized = {};
        for (const [key, value] of Object.entries(obj)){
            const trimmedKey = key.trim();
            const preserveStringValue = context.preserveStringValueKeys?.includes(trimmedKey) ?? false;
            const normalizedValue = 'string' == typeof value ? preserveStringValue ? value : value.trim() : normalizeJsonObject(value, context);
            normalized[trimmedKey] = normalizedValue;
        }
        return normalized;
    }
    return 'string' == typeof obj ? obj.trim() : obj;
}
function shouldRepairUiTarsLocateJson(source) {
    return 'locate' === source || 'section-locator' === source || 'planning-action-param' === source;
}
function preprocessUiTarsLocateJson(input) {
    if (input.includes('bbox')) while(/\d+\s+\d+/.test(input))input = input.replace(/(\d+)\s+(\d+)/g, '$1,$2');
    return input;
}
const uiTarsJsonParser = (raw, context = {
    source: 'generic-object'
})=>{
    const { source } = context;
    try {
        return safeParseJson(raw, context);
    } catch (firstError) {
        if (!shouldRepairUiTarsLocateJson(source)) throw firstError;
        const jsonString = preprocessUiTarsLocateJson(extractJSONFromCodeBlock(raw));
        try {
            return normalizeJsonObject(JSON.parse(jsonrepair(jsonString)), context);
        } catch (error) {
            throw Error(`failed to parse LLM response into JSON. Error - ${String(error ?? firstError ?? 'unknown error')}. Response - \n ${raw}`);
        }
    }
};
function parseUiTarsRawLocateValue(input) {
    const bbox = unwrapCoordinateListLikeInput(input);
    if ('string' == typeof bbox) {
        assert(/^(\d+)\s(\d+)\s(\d+)\s(\d+)$/.test(bbox.trim()), `invalid bbox data string for ui-tars mode: ${bbox}`);
        const splitted = bbox.split(' ');
        if (4 === splitted.length) return {
            type: 'bbox',
            coordinates: [
                Number(splitted[0]),
                Number(splitted[1]),
                Number(splitted[2]),
                Number(splitted[3])
            ]
        };
        throw new Error(`invalid bbox data string for ui-tars mode: ${bbox}`);
    }
    let bboxList = [];
    if (Array.isArray(bbox) && 'string' == typeof bbox[0]) bbox.forEach((item)=>{
        if ('string' == typeof item && item.includes(',')) {
            const [x, y] = item.split(',');
            bboxList.push(Number(x.trim()), Number(y.trim()));
        } else if ('string' == typeof item && item.includes(' ')) {
            const [x, y] = item.split(' ');
            bboxList.push(Number(x.trim()), Number(y.trim()));
        } else bboxList.push(Number(item));
    });
    else bboxList = bbox;
    if (4 === bboxList.length || 5 === bboxList.length) return {
        type: 'bbox',
        coordinates: [
            bboxList[0],
            bboxList[1],
            bboxList[2],
            bboxList[3]
        ]
    };
    if (6 === bboxList.length || 2 === bboxList.length || 3 === bboxList.length || 7 === bboxList.length) return {
        type: 'point',
        coordinates: [
            bboxList[0],
            bboxList[1]
        ]
    };
    if (8 === bbox.length) return {
        type: 'bbox',
        coordinates: [
            bboxList[0],
            bboxList[1],
            bboxList[4],
            bboxList[5]
        ]
    };
    const msg = `invalid bbox data for ui-tars mode: ${JSON.stringify(bbox)} `;
    throw new Error(msg);
}
function createUiTarsAdapter(uiTarsModelVersion) {
    return {
        jsonParser: uiTarsJsonParser,
        chatCompletion: {
            unsupportedUserConfig: [
                'reasoningEnabled',
                'reasoningEffort',
                'reasoningBudget'
            ],
            buildChatCompletionParams: ({ midsceneDefaults, userConfig })=>{
                const commonOverrideConfig = {};
                if (void 0 !== userConfig.temperature) commonOverrideConfig.temperature = userConfig.temperature;
                return {
                    config: {
                        ...midsceneDefaults,
                        ...commonOverrideConfig
                    }
                };
            }
        },
        planning: {
            kind: 'custom',
            cacheEnabled: false,
            defaultReplanningCycleLimit: defaultVlmUiTarsReplanningCycleLimit,
            planFn: (userInstruction, options)=>uiTarsPlanning(userInstruction, options, uiTarsModelVersion)
        },
        locate: {
            resultAdapter: {
                coordinates: {
                    shape: 'bbox',
                    order: 'xy',
                    normalizedBy: 1000
                },
                parseRawLocateValue: parseUiTarsRawLocateValue
            }
        }
    };
}
const uiTarsDoubao15Adapter = createUiTarsAdapter(UITarsModelVersion.DOUBAO_1_5_20B);
const uiTarsAdapters = {
    'vlm-ui-tars': createUiTarsAdapter(UITarsModelVersion.V1_0),
    'vlm-ui-tars-doubao': uiTarsDoubao15Adapter,
    'vlm-ui-tars-doubao-1.5': uiTarsDoubao15Adapter
};
export { uiTarsAdapters };

//# sourceMappingURL=adapter.mjs.map