const MAX_DEPTH = 5;
const MAX_ARRAY_SCAN = 50;
const MAX_DETAILS = 12;
function describeType(value) {
    if (value === null)
        return 'null';
    if (Array.isArray(value))
        return 'array';
    return typeof value;
}
/** Whether `value` satisfies a single JSON Schema primitive `type` keyword. */
function matchesType(value, type) {
    switch (type) {
        case 'string':
        case 'number':
        case 'integer':
        case 'boolean':
            // Scalar expected: accept any non-structured, non-null value. This
            // rejects objects/arrays/null (the real bugs) while tolerating
            // scalar↔scalar mismatches (e.g. "5" for a number).
            return value !== null && typeof value !== 'object';
        case 'array':
            return Array.isArray(value);
        case 'object':
            return (value !== null && typeof value === 'object' && !Array.isArray(value));
        case 'null':
            return value === null;
        default:
            // Unknown type keyword → don't flag.
            return true;
    }
}
function typesOf(schema) {
    if (Array.isArray(schema.type))
        return schema.type;
    if (typeof schema.type === 'string')
        return [schema.type];
    return [];
}
function checkValue(value, schema, path, depth, out) {
    if (out.length >= MAX_DETAILS || depth > MAX_DEPTH)
        return;
    if (value === undefined)
        return; // presence is handled by per-tool validators
    const types = typesOf(schema);
    // Type check (only when a concrete type is declared).
    if (types.length > 0 && !types.some(t => matchesType(value, t))) {
        out.push({
            path,
            expected: types.join(' | '),
            received: describeType(value),
        });
        return; // structure mismatched — don't descend into it
    }
    // Enum membership (scalars only; comparing structured values is unreliable).
    if (Array.isArray(schema.enum) &&
        value !== null &&
        typeof value !== 'object' &&
        !schema.enum.includes(value)) {
        out.push({
            path,
            expected: `one of ${schema.enum.map(v => JSON.stringify(v)).join(', ')}`,
            received: JSON.stringify(value),
        });
        return;
    }
    // Recurse into array elements.
    if (Array.isArray(value) && schema.items) {
        const limit = Math.min(value.length, MAX_ARRAY_SCAN);
        for (let i = 0; i < limit; i++) {
            checkValue(value[i], schema.items, `${path}[${i}]`, depth + 1, out);
            if (out.length >= MAX_DETAILS)
                return;
        }
        return;
    }
    // Recurse into object properties that are present.
    if (schema.properties &&
        value !== null &&
        typeof value === 'object' &&
        !Array.isArray(value)) {
        const obj = value;
        for (const [key, propSchema] of Object.entries(schema.properties)) {
            if (key in obj) {
                const childPath = path ? `${path}.${key}` : key;
                checkValue(obj[key], propSchema, childPath, depth + 1, out);
                if (out.length >= MAX_DETAILS)
                    return;
            }
        }
    }
}
/**
 * Type-check parsed tool arguments against a JSON schema. Returns one detail
 * per high-confidence type error (empty array when the args look well-typed or
 * the schema is too complex to check confidently).
 */
export function validateArgsAgainstSchema(args, schema) {
    if (!schema || typeof schema !== 'object')
        return [];
    const out = [];
    checkValue(args, schema, '', 0, out);
    return out;
}
/**
 * Pull the raw JSON Schema out of an AI SDK tool's `inputSchema`. Tools built
 * with `jsonSchema(...)` expose it as `inputSchema.jsonSchema`. Returns
 * undefined for anything else (or a promise-like / non-object), so callers
 * simply skip schema validation rather than risk a false positive.
 */
export function getToolJsonSchema(tool) {
    const input = tool?.inputSchema;
    if (!input || typeof input !== 'object')
        return undefined;
    const js = input.jsonSchema;
    if (!js || typeof js !== 'object')
        return undefined;
    if ('then' in js)
        return undefined; // promise-like — skip
    return js;
}
//# sourceMappingURL=schema-validate.js.map