"use strict";
var _MainThreadChatAgents_proxy;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MainThreadChatAgents = void 0;
const tslib_1 = require("tslib");
const di_1 = require("@opensumi/di");
const chat_internal_service_1 = require("@opensumi/ide-ai-native/lib/browser/chat/chat.internal.service");
const types_1 = require("@opensumi/ide-ai-native/lib/browser/types");
const inline_chat_controller_1 = require("@opensumi/ide-ai-native/lib/browser/widget/inline-chat/inline-chat-controller");
const common_1 = require("@opensumi/ide-ai-native/lib/common");
const ide_connection_1 = require("@opensumi/ide-connection");
const ide_core_common_1 = require("@opensumi/ide-core-common");
const stream_1 = require("@opensumi/ide-utils/lib/stream");
const sumi_1 = require("../../common/sumi");
let MainThreadChatAgents = class MainThreadChatAgents {
    /**
     * ai-native 由上层业务激活，对应的 service 可能不存在
     */
    get chatAgentService() {
        try {
            return this.injector.get(common_1.IChatAgentService);
        }
        catch (err) {
            return null;
        }
    }
    get inlineChatFeatureRegistry() {
        try {
            return this.injector.get(ide_core_common_1.InlineChatFeatureRegistryToken);
        }
        catch (err) {
            return null;
        }
    }
    get chatInternalService() {
        try {
            return this.injector.get(chat_internal_service_1.ChatInternalService);
        }
        catch (err) {
            return null;
        }
    }
    constructor(rpcProtocol, injector) {
        this.injector = injector;
        _MainThreadChatAgents_proxy.set(this, void 0);
        this.agents = new Map();
        this.pendingProgress = new Map();
        this.responsePartHandlePool = 0;
        this.activeResponsePartPromises = new Map();
        tslib_1.__classPrivateFieldSet(this, _MainThreadChatAgents_proxy, rpcProtocol.getProxy(sumi_1.ExtHostSumiAPIIdentifier.ExtHostChatAgents), "f");
    }
    $registerInlineChatProvider(handle, name, metadata) {
        if (!this.inlineChatFeatureRegistry || !this.chatInternalService) {
            return;
        }
        const d = this.inlineChatFeatureRegistry.registerInteractiveInput({ handleStrategy: () => types_1.ERunStrategy.PREVIEW }, {
            providePreviewStrategy: async (editor, selection, value, token) => {
                var _a;
                const controller = new inline_chat_controller_1.InlineChatController({ enableCodeblockRender: !!metadata.enableCodeblockRender });
                const request = this.chatInternalService.createRequest(value, name);
                const stream = new stream_1.SumiReadableStream();
                controller.mountReadable(stream);
                const progressCallback = (progress) => {
                    if (token.isCancellationRequested) {
                        stream.abort();
                        return;
                    }
                    stream.emitData(progress);
                };
                this.pendingProgress.set(request.requestId, progressCallback);
                const requestProps = {
                    sessionId: (_a = this.chatInternalService) === null || _a === void 0 ? void 0 : _a.sessionModel.sessionId,
                    requestId: request.requestId,
                    message: request.message.prompt,
                    command: request.message.command,
                };
                tslib_1.__classPrivateFieldGet(this, _MainThreadChatAgents_proxy, "f")
                    .$invokeAgent(handle, requestProps, { history: [] }, token)
                    .then((result) => {
                    if (!result) {
                        stream.end();
                        return;
                    }
                    if (!token.isCancellationRequested) {
                        if (result.errorDetails) {
                            request.response.setErrorDetails(result.errorDetails);
                        }
                        stream.end();
                    }
                    else {
                        stream.abort();
                    }
                })
                    .finally(() => {
                    this.pendingProgress.delete(request.requestId);
                });
                return controller;
            },
        });
        this.agents.set(handle, {
            name,
            dispose: d.dispose,
        });
    }
    $registerAgent(handle, name, metadata) {
        if (!this.chatAgentService) {
            return;
        }
        const d = this.chatAgentService.registerAgent({
            id: name,
            metadata,
            invoke: async (request, progress, history, token) => {
                var _a;
                this.pendingProgress.set(request.requestId, progress);
                try {
                    return ((_a = (await tslib_1.__classPrivateFieldGet(this, _MainThreadChatAgents_proxy, "f").$invokeAgent(handle, request, {
                        history: history.map((item) => ({
                            role: ide_core_common_1.CoreMessgaeRoleMap[item.role],
                            content: item.content.toString(),
                        })),
                    }, token))) !== null && _a !== void 0 ? _a : {});
                }
                finally {
                    this.pendingProgress.delete(request.requestId);
                }
            },
            provideSlashCommands: async (token) => {
                var _a;
                if (!((_a = this.agents.get(handle)) === null || _a === void 0 ? void 0 : _a.hasSlashCommands)) {
                    return [];
                }
                return tslib_1.__classPrivateFieldGet(this, _MainThreadChatAgents_proxy, "f").$provideSlashCommands(handle, token);
            },
            provideFollowups: async (sessionId, token) => {
                var _a;
                if (!((_a = this.agents.get(handle)) === null || _a === void 0 ? void 0 : _a.hasFollowups)) {
                    return [];
                }
                return tslib_1.__classPrivateFieldGet(this, _MainThreadChatAgents_proxy, "f").$provideFollowups(handle, sessionId, token);
            },
            provideSampleQuestions: async (token) => {
                var _a;
                if (!((_a = this.agents.get(handle)) === null || _a === void 0 ? void 0 : _a.hasSampleQuestions)) {
                    return [];
                }
                return tslib_1.__classPrivateFieldGet(this, _MainThreadChatAgents_proxy, "f").$provideSampleQuestions(handle, token);
            },
            provideChatWelcomeMessage: async (token) => {
                var _a;
                if (!((_a = this.agents.get(handle)) === null || _a === void 0 ? void 0 : _a.hasChatWelcomMessage)) {
                    return undefined;
                }
                return tslib_1.__classPrivateFieldGet(this, _MainThreadChatAgents_proxy, "f").$provideChatWelcomeMessage(handle, token);
            },
        });
        this.agents.set(handle, {
            name,
            dispose: d.dispose,
            hasSlashCommands: metadata.hasSlashCommands,
            hasFollowups: metadata.hasFollowups,
        });
    }
    $updateAgent(handle, metadataUpdate) {
        if (!this.chatAgentService) {
            return;
        }
        const data = this.agents.get(handle);
        if (!data) {
            throw new Error(`No agent with handle ${handle} registered`);
        }
        data.hasSlashCommands = metadataUpdate.hasSlashCommands;
        data.hasFollowups = metadataUpdate.hasFollowups;
        data.hasSampleQuestions = metadataUpdate.hasSampleQuestions;
        data.hasChatWelcomMessage = metadataUpdate.hasChatWelcomMessage;
        data.isDefault = metadataUpdate.isDefault;
        this.chatAgentService.updateAgent(data.name, metadataUpdate);
    }
    async $handleProgressChunk(requestId, progress, responsePartHandle) {
        var _a, _b;
        if (progress.kind === 'asyncContent') {
            const handle = ++this.responsePartHandlePool;
            const responsePartId = `${requestId}_${handle}`;
            const deferredContentPromise = new ide_core_common_1.Deferred();
            this.activeResponsePartPromises.set(responsePartId, deferredContentPromise);
            (_a = this.pendingProgress.get(requestId)) === null || _a === void 0 ? void 0 : _a({ ...progress, resolvedContent: deferredContentPromise.promise });
            return handle;
        }
        else if (typeof responsePartHandle === 'number') {
            const responsePartId = `${requestId}_${responsePartHandle}`;
            const deferredContentPromise = this.activeResponsePartPromises.get(responsePartId);
            if (deferredContentPromise) {
                if (progress.kind === 'content') {
                    deferredContentPromise.resolve(progress.content);
                }
                else if (progress.kind === 'treeData') {
                    deferredContentPromise.resolve(progress);
                }
                this.activeResponsePartPromises.delete(responsePartId);
            }
            return responsePartHandle;
        }
        (_b = this.pendingProgress.get(requestId)) === null || _b === void 0 ? void 0 : _b(progress);
    }
    $unregisterAgent(handle) {
        var _a;
        (_a = this.agents.get(handle)) === null || _a === void 0 ? void 0 : _a.dispose();
        this.agents.delete(handle);
    }
    $populateChatInput(handle, param) {
        if (!this.chatAgentService) {
            return;
        }
        const data = this.agents.get(handle);
        if (!data) {
            throw new Error(`No agent with handle ${handle} registered`);
        }
        this.chatAgentService.populateChatInput(data.name, {
            command: param.command,
            message: param.prompt,
        });
    }
    $sendMessage(chunk) {
        if (!this.chatAgentService) {
            return;
        }
        this.chatAgentService.sendMessage(chunk);
    }
    dispose() {
        this.agents.forEach((agent) => {
            agent.dispose();
        });
        this.agents.clear();
    }
};
exports.MainThreadChatAgents = MainThreadChatAgents;
_MainThreadChatAgents_proxy = new WeakMap();
exports.MainThreadChatAgents = MainThreadChatAgents = tslib_1.__decorate([
    (0, di_1.Injectable)({ multiple: true }),
    tslib_1.__metadata("design:paramtypes", [Object, di_1.Injector])
], MainThreadChatAgents);
//# sourceMappingURL=main.thread.chat-agents.js.map