"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.KnowhowSimpleClient = exports.KNOWHOW_API_URL = void 0;
exports.loadKnowhowJwt = loadKnowhowJwt;
const crypto_1 = require("crypto");
const http_1 = __importDefault(require("../utils/http"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
function loadKnowhowJwt() {
    const jwtFile = path_1.default.join(process.cwd(), ".knowhow", ".jwt");
    if (!fs_1.default.existsSync(jwtFile)) {
        return "";
    }
    const jwt = fs_1.default.readFileSync(jwtFile, "utf-8").trim();
    return jwt;
}
exports.KNOWHOW_API_URL = process.env.KNOWHOW_API_URL || "https://api.knowhow.tyvm.ai";
class KnowhowSimpleClient {
    baseUrl;
    jwt;
    headers = {};
    jwtValidated = false;
    constructor(baseUrl = exports.KNOWHOW_API_URL, jwt = loadKnowhowJwt()) {
        this.baseUrl = baseUrl;
        this.jwt = jwt;
        this.setJwt(jwt);
    }
    refreshJwt() {
        const freshJwt = loadKnowhowJwt();
        if (freshJwt) {
            this.setJwt(freshJwt);
            this.jwtValidated = false;
        }
    }
    setJwt(jwt) {
        this.jwt = jwt;
        this.headers = {
            Authorization: `Bearer ${this.jwt}`,
        };
    }
    async checkJwt() {
        if (!this.jwt) {
            throw new Error("No JWT found. Please login first.");
        }
        if (!this.jwtValidated) {
            try {
                this.jwtValidated = true;
                const response = await this.me();
                const user = response.data.user;
                const orgs = user.orgs;
                const orgId = response.data.orgId;
                const currentOrg = orgs.find((org) => {
                    return org.organizationId === orgId;
                });
            }
            catch (error) {
                throw new Error("Invalid JWT. Please login again.");
            }
        }
    }
    async me() {
        if (!this.jwt) {
            throw new Error("No JWT found. Please login first.");
        }
        return http_1.default.get(`${this.baseUrl}/api/users/me`, {
            headers: this.headers,
        });
    }
    async getPresignedUploadUrl(source) {
        await this.checkJwt();
        const id = source.remoteId;
        const presignedUrlResp = await http_1.default.post(`${this.baseUrl}/api/org-embeddings/${id}/upload`, {}, {
            headers: this.headers,
        });
        console.log(presignedUrlResp.data);
        const presignedUrl = presignedUrlResp.data.uploadUrl;
        return presignedUrl;
    }
    async getPresignedDownloadUrl(source) {
        await this.checkJwt();
        const id = source.remoteId;
        const presignedUrlResp = await http_1.default.post(`${this.baseUrl}/api/org-embeddings/${id}/download`, {}, {
            headers: this.headers,
        });
        const presignedUrl = presignedUrlResp.data.downloadUrl;
        return presignedUrl;
    }
    async getOrgEmbedding(id) {
        await this.checkJwt();
        const resp = await http_1.default.get(`${this.baseUrl}/api/org-embeddings/${id}`, {
            headers: this.headers,
        });
        return resp.data;
    }
    async updateEmbeddingMetadata(id, data) {
        await this.checkJwt();
        return http_1.default.put(`${this.baseUrl}/api/org-embeddings/${id}`, data, {
            headers: this.headers,
        });
    }
    async createChatCompletion(options) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/chat/completions`, options, {
            headers: this.headers,
        });
    }
    async createEmbedding(options) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/embeddings`, options, {
            headers: this.headers,
        });
    }
    async getModels(type = "all") {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/proxy/v1/models?type=${type}`, {
            headers: this.headers,
        });
    }
    async createAudioTranscription(options) {
        await this.checkJwt();
        const formData = new FormData();
        if (Buffer.isBuffer(options.file)) {
            formData.append("file", new Blob([new Uint8Array(options.file)]), options.fileName || "audio.mp3");
        }
        else {
            formData.append("file", options.file);
        }
        if (options.model)
            formData.append("model", options.model);
        if (options.language)
            formData.append("language", options.language);
        if (options.prompt)
            formData.append("prompt", options.prompt);
        if (options.response_format)
            formData.append("response_format", options.response_format);
        if (options.temperature != null)
            formData.append("temperature", String(options.temperature));
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/audio/transcriptions`, formData, { headers: { ...this.headers } });
    }
    async createAudioGeneration(options) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/audio/generations`, options, { headers: this.headers });
    }
    async createImageGeneration(options) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/images/generations`, options, { headers: this.headers });
    }
    async createVideoGeneration(options) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/videos/generations`, options, { headers: this.headers });
    }
    async getVideoStatus(options) {
        await this.checkJwt();
        const { jobId, ...rest } = options;
        return http_1.default.get(`${this.baseUrl}/api/proxy/v1/videos/${jobId}/status`, { headers: this.headers, params: rest });
    }
    async downloadVideo(options) {
        await this.checkJwt();
        const { fileId } = options;
        return http_1.default.get(`${this.baseUrl}/api/proxy/v1/videos/${fileId}/content`, { headers: this.headers, responseType: "arraybuffer" });
    }
    async uploadFile(options) {
        await this.checkJwt();
        const body = {
            data: options.data.toString("base64"),
            mimeType: options.mimeType,
            fileName: options.fileName,
            displayName: options.displayName,
        };
        return http_1.default.post(`${this.baseUrl}/api/proxy/v1/files`, body, { headers: this.headers });
    }
    async downloadFile(options) {
        await this.checkJwt();
        const { fileId } = options;
        return http_1.default.get(`${this.baseUrl}/api/proxy/v1/files/${fileId}/content`, { headers: this.headers, responseType: "arraybuffer" });
    }
    async createChatTask(request) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/chat/tasks`, request, {
            headers: this.headers,
        });
    }
    async updateChatTask(taskId, updates) {
        await this.checkJwt();
        return http_1.default.put(`${this.baseUrl}/api/chat/tasks/${taskId}`, updates, {
            headers: this.headers,
        });
    }
    async getTaskDetails(taskId) {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/org-agent-tasks/${taskId}`, {
            headers: this.headers,
        });
    }
    async getPendingMessages(taskId) {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/org-agent-tasks/${taskId}/pending-messages`, {
            headers: this.headers,
        });
    }
    async markMessagesAsProcessed(taskId, messageIds) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/org-agent-tasks/${taskId}/pending-messages/mark-processed`, { messageIds }, {
            headers: this.headers,
        });
    }
    async sendMessageToAgent(taskId, message, role = "user") {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/org-agent-tasks/${taskId}/messages`, { message, role }, {
            headers: this.headers,
        });
    }
    async pauseAgent(taskId) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/org-agent-tasks/${taskId}/pause`, {}, {
            headers: this.headers,
        });
    }
    async resumeAgent(taskId) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/org-agent-tasks/${taskId}/resume`, {}, {
            headers: this.headers,
        });
    }
    async getTaskThreads(taskId) {
        const response = await this.getTaskDetails(taskId);
        return response.data.threads || [];
    }
    async killAgent(taskId) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/org-agent-tasks/${taskId}/kill`, {}, {
            headers: this.headers,
        });
    }
    async listOrgFiles() {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/org-files`, { headers: this.headers });
    }
    async createOrgFile(fileName, folderPath) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/org-files`, { fileName, folderPath, name: fileName }, { headers: this.headers });
    }
    async getOrgFileText(fileId) {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/org-files/${fileId}/text`, {
            headers: this.headers,
            params: { reading: "true" },
        });
    }
    async updateOrgFileText(fileId, text) {
        await this.checkJwt();
        return http_1.default.put(`${this.baseUrl}/api/org-files/${fileId}/text`, { text }, { headers: this.headers });
    }
    async findOrgFileByPath(remotePath) {
        const lastSlash = remotePath.lastIndexOf("/");
        const rawFolder = lastSlash >= 0 ? remotePath.substring(0, lastSlash + 1) : "/";
        const folderPath = rawFolder === "/" ? rawFolder : rawFolder;
        const fileName = lastSlash >= 0 ? remotePath.substring(lastSlash + 1) : remotePath;
        const response = await this.listOrgFiles();
        const files = response.data;
        const isRoot = folderPath === "/" || folderPath === "";
        return (files.find((f) => f.fileName === fileName &&
            (f.folderPath === folderPath ||
                (isRoot && (f.folderPath === "/" || f.folderPath === "")))) || null);
    }
    async findOrCreateOrgFileByPath(remotePath) {
        const existing = await this.findOrgFileByPath(remotePath);
        if (existing)
            return existing;
        const lastSlash = remotePath.lastIndexOf("/");
        const folderPath = lastSlash >= 0 ? remotePath.substring(0, lastSlash + 1) || "/" : "/";
        const fileName = lastSlash >= 0 ? remotePath.substring(lastSlash + 1) : remotePath;
        const response = await this.createOrgFile(fileName, folderPath);
        return response.data;
    }
    async getOrgFilePresignedDownloadUrl(filePath) {
        await this.checkJwt();
        const file = await this.findOrgFileByPath(filePath);
        if (!file) {
            throw new Error(`File not found: ${filePath}`);
        }
        const response = await http_1.default.post(`${this.baseUrl}/api/org-files/download/${file.id}`, {}, { headers: this.headers });
        return {
            downloadUrl: response.data.downloadUrl,
            checksumSHA256: response.data.checksumSHA256 ?? null,
        };
    }
    async markOrgFileUploadComplete(filePath) {
        await this.checkJwt();
        const file = await this.findOrgFileByPath(filePath);
        if (!file) {
            throw new Error(`File not found: ${filePath}`);
        }
        await http_1.default.post(`${this.baseUrl}/api/org-files/upload/${file.id}/complete`, {}, { headers: this.headers });
    }
    async getOrgFilePresignedUploadUrl(filePath, localFilePath) {
        await this.checkJwt();
        const file = await this.findOrCreateOrgFileByPath(filePath);
        const lastSlash = filePath.lastIndexOf("/");
        const fileName = lastSlash >= 0 ? filePath.substring(lastSlash + 1) : filePath;
        let sha256Hash;
        if (localFilePath) {
            const fileContent = fs_1.default.readFileSync(localFilePath);
            sha256Hash = (0, crypto_1.createHash)("sha256").update(fileContent).digest("base64");
        }
        const response = await http_1.default.post(`${this.baseUrl}/api/org-files/upload/${file.id}`, { fileName, sha256Hash }, { headers: this.headers });
        return response.data.uploadUrl;
    }
    async getGitCredential(repo) {
        await this.checkJwt();
        const response = await http_1.default.post(`${this.baseUrl}/api/github/git-credential`, { repo }, { headers: this.headers });
        return response.data;
    }
    async listCloudWorkers() {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/cloud-workers`, { headers: this.headers });
    }
    async createCloudWorker(data) {
        await this.checkJwt();
        return http_1.default.post(`${this.baseUrl}/api/cloud-workers`, data, { headers: this.headers });
    }
    async getCloudWorker(id) {
        await this.checkJwt();
        return http_1.default.get(`${this.baseUrl}/api/cloud-workers/${id}`, { headers: this.headers });
    }
    async updateCloudWorker(id, data) {
        await this.checkJwt();
        return http_1.default.put(`${this.baseUrl}/api/cloud-workers/${id}`, data, { headers: this.headers });
    }
    async createSessionPlaceholder(request = {}) {
        await this.checkJwt();
        const response = await http_1.default.post(`${this.baseUrl}/api/chat/sessions/placeholder`, request, { headers: this.headers });
        return response.data;
    }
    async createMessagePlaceholder(sessionId, request) {
        await this.checkJwt();
        const response = await http_1.default.post(`${this.baseUrl}/api/chat/sessions/${sessionId}/messages/placeholder`, request, { headers: this.headers });
        return response.data;
    }
}
exports.KnowhowSimpleClient = KnowhowSimpleClient;
//# sourceMappingURL=KnowhowClient.js.map