import { safeJsonParse, safeJsonStringify, } from "../../../../util/log-sanitizer.js";
import { getLogger } from "../../../../util/logger.js";
import { ToolExecutionError } from "../../tools2/types.js";
import { classifyExternalErrorSeverity } from "./errors.js";
export const MAX_QUERY_RESPONSE_TOKENS = 10_000;
export async function executeRequest(context, integrationId, request) {
    if (!context.peer) {
        getLogger().warn(`[ai-service] Cannot execute integration: no peer. id=${integrationId}`);
    }
    const response = await context.peer?.call.aiExecuteRequestToIntegration({
        integrationId,
        request,
    });
    if (!response || response.error) {
        const integrationError = response?.error ?? "Unknown error";
        const errorMessage = typeof integrationError === "string"
            ? integrationError
            : (safeJsonStringify(integrationError) ?? "Unknown error");
        const severity = classifyExternalErrorSeverity(errorMessage);
        throw new ToolExecutionError(errorMessage, {
            toolName: "executeRequestToIntegration",
            input: { integrationId, request },
            context: {},
            severity,
        });
    }
    // truncate results
    const truncatedResponse = truncateToTokens(response.response, MAX_QUERY_RESPONSE_TOKENS);
    return {
        data: truncatedResponse.result,
        isPartial: truncatedResponse.truncated,
    };
}
// always generate a valid JSON
export function truncateToTokens(obj, maxTokens) {
    const maxChars = maxTokens * 3;
    const json = safeJsonStringify(obj);
    if (json.length < maxChars) {
        return { result: json, truncated: false };
    }
    // Truncate the object structure to ensure valid JSON
    const parsed = typeof obj === "string" ? safeJsonParse(obj) : obj;
    if (parsed === undefined) {
        // Not valid JSON (e.g. HTML or plain text) — truncate the raw string
        return { result: obj.slice(0, maxChars), truncated: true };
    }
    const truncated = truncateObject(parsed, maxChars);
    return { result: safeJsonStringify(truncated), truncated: true };
}
function truncateObject(obj, maxChars) {
    // Base case: primitive values
    if (obj === null || obj === undefined || typeof obj !== "object") {
        return obj;
    }
    // Handle arrays
    if (Array.isArray(obj)) {
        const truncated = [];
        for (let i = 0; i < obj.length; i++) {
            const item = truncateObject(obj[i], maxChars);
            const testArray = [...truncated, item];
            const testJson = safeJsonStringify(testArray);
            if (testJson.length > maxChars) {
                // Adding this item would exceed the limit, stop here
                break;
            }
            truncated.push(item);
        }
        return truncated;
    }
    // Handle objects
    const truncated = {};
    const entries = Object.entries(obj);
    for (const [key, value] of entries) {
        const truncatedValue = truncateObject(value, maxChars);
        const testObj = { ...truncated, [key]: truncatedValue };
        const testJson = safeJsonStringify(testObj);
        if (testJson.length > maxChars) {
            // Adding this property would exceed the limit, stop here
            break;
        }
        truncated[key] = truncatedValue;
    }
    return truncated;
}
//# sourceMappingURL=internal.js.map