import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { append, clearNode, WindowIntervalTimer, getWindow, $ as $$1, show, hide, scheduleAtNextAnimationFrame } from '../../../../base/browser/dom.js';
import { alert } from '../../../../base/browser/ui/aria/aria.js';
import { Button } from '../../../../base/browser/ui/button/button.js';
import { renderIcon } from '../../../../base/browser/ui/iconLabel/iconLabels.js';
import { distinct } from '../../../../base/common/arrays.js';
import { disposableTimeout } from '../../../../base/common/async.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { Emitter } from '../../../../base/common/event.js';
import { MarkdownString } from '../../../../base/common/htmlContent.js';
import { Disposable, DisposableStore, toDisposable } from '../../../../base/common/lifecycle.js';
import { ResourceMap } from '../../../../base/common/map.js';
import { FileAccess, matchesSomeScheme, Schemas } from '../../../../base/common/network.js';
import { clamp } from '../../../../base/common/numbers.js';
import { basename } from '../../../../base/common/path.js';
import { basenameOrAuthority } from '../../../../base/common/resources.js';
import { equalsIgnoreCase } from '../../../../base/common/strings.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { URI } from '../../../../base/common/uri.js';
import { MarkdownRenderer } from '../../../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js';
import { Range } from '../../../../editor/common/core/range.js';
import { ITextModelService } from '../../../../editor/common/services/resolverService.js';
import { localizeWithPath } from '../../../../nls.js';
import { createActionViewItem, MenuEntryActionViewItem } from '../../../../platform/actions/browser/menuEntryActionViewItem.js';
import { MenuWorkbenchToolBar } from '../../../../platform/actions/browser/toolbar.js';
import { MenuId, MenuItemAction } from '../../../../platform/actions/common/actions.js';
import { ICommandService } from '../../../../platform/commands/common/commands.service.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.service.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { FileKind, FileType } from '../../../../platform/files/common/files.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
import { WorkbenchCompressibleAsyncDataTree, WorkbenchList } from '../../../../platform/list/browser/listService.js';
import { ILogService } from '../../../../platform/log/common/log.service.js';
import { IOpenerService } from '../../../../platform/opener/common/opener.service.js';
import { defaultButtonStyles } from '../../../../platform/theme/browser/defaultStyles.js';
import { ColorScheme } from '../../../../platform/theme/common/theme.js';
import { IThemeService } from '../../../../platform/theme/common/themeService.service.js';
import { ResourceLabels } from '../../../browser/labels.js';
import { GeneratingPhrase } from './chat.js';
import { ChatFollowups } from './chatFollowups.js';
import { ChatMarkdownDecorationsRenderer } from './chatMarkdownDecorationsRenderer.js';
import { ChatCodeBlockContentProvider, parseLocalFileData, CodeBlockPart, localFileLanguageId } from './codeBlockPart.js';
import { CONTEXT_RESPONSE, CONTEXT_REQUEST, CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND, CONTEXT_CHAT_RESPONSE_SUPPORT_ISSUE_REPORTING, CONTEXT_RESPONSE_VOTE, CONTEXT_RESPONSE_FILTERED } from '../common/chatContextKeys.js';
import { chatAgentLeader, chatSubcommandLeader } from '../common/chatParserTypes.js';
import { InteractiveSessionVoteDirection } from '../common/chatService.js';
import { IChatVariablesService } from '../common/chatVariables.service.js';
import { isResponseVM, isRequestVM, isWelcomeVM } from '../common/chatViewModel.js';
import { getNWords } from '../common/chatWordCounter.js';
import { createFileIconThemableTreeContainerScope } from '../../files/browser/views/explorerView.js';
import { annotateSpecialMarkdownContent } from '../common/annotations.js';
var ChatListItemRenderer_1, ContentReferencesListRenderer_1;
const _moduleId = "vs/workbench/contrib/chat/browser/chatListRenderer";
const $ = $$1;
let ChatListItemRenderer = class ChatListItemRenderer extends Disposable {
    static { ChatListItemRenderer_1 = this; }
    static { this.ID = 'item'; }
    constructor(editorOptions, location, rendererOptions, delegate, codeBlockModelCollection, overflowWidgetsDomNode, instantiationService, configService, logService, openerService, contextKeyService, themeService, commandService, textModelService) {
        super();
        this.location = location;
        this.rendererOptions = rendererOptions;
        this.delegate = delegate;
        this.codeBlockModelCollection = codeBlockModelCollection;
        this.instantiationService = instantiationService;
        this.logService = logService;
        this.openerService = openerService;
        this.contextKeyService = contextKeyService;
        this.themeService = themeService;
        this.commandService = commandService;
        this.textModelService = textModelService;
        this.codeBlocksByResponseId = ( (new Map()));
        this.codeBlocksByEditorUri = ( (new ResourceMap()));
        this.fileTreesByResponseId = ( (new Map()));
        this.focusedFileTreesByResponseId = ( (new Map()));
        this._onDidClickFollowup = this._register(( (new Emitter())));
        this.onDidClickFollowup = this._onDidClickFollowup.event;
        this._onDidChangeItemHeight = this._register(( (new Emitter())));
        this.onDidChangeItemHeight = this._onDidChangeItemHeight.event;
        this._currentLayoutWidth = 0;
        this._isVisible = true;
        this._onDidChangeVisibility = this._register(( (new Emitter())));
        this._usedReferencesEnabled = false;
        this.renderer = this._register(this.instantiationService.createInstance(MarkdownRenderer, {}));
        this.markdownDecorationsRenderer = this.instantiationService.createInstance(ChatMarkdownDecorationsRenderer);
        this._editorPool = this._register(this.instantiationService.createInstance(EditorPool, editorOptions, delegate, overflowWidgetsDomNode));
        this._treePool = this._register(this.instantiationService.createInstance(TreePool, this._onDidChangeVisibility.event));
        this._contentReferencesListPool = this._register(this.instantiationService.createInstance(ContentReferencesListPool, this._onDidChangeVisibility.event));
        this._register(this.instantiationService.createInstance(ChatCodeBlockContentProvider));
        this._usedReferencesEnabled = configService.getValue('chat.experimental.usedReferences') ?? true;
        this._register(configService.onDidChangeConfiguration(e => {
            if (e.affectsConfiguration('chat.experimental.usedReferences')) {
                this._usedReferencesEnabled = configService.getValue('chat.experimental.usedReferences') ?? true;
            }
        }));
    }
    get templateId() {
        return ChatListItemRenderer_1.ID;
    }
    editorsInUse() {
        return this._editorPool.inUse();
    }
    traceLayout(method, message) {
        {
            this.logService.trace(`ChatListItemRenderer#${method}: ${message}`);
        }
    }
    getProgressiveRenderRate(element) {
        if (element.isComplete) {
            return 80;
        }
        if (element.contentUpdateTimings && element.contentUpdateTimings.impliedWordLoadRate) {
            const minRate = 12;
            const maxRate = 80;
            const rateBoost = 1.5;
            const rate = element.contentUpdateTimings.impliedWordLoadRate * rateBoost;
            return clamp(rate, minRate, maxRate);
        }
        return 8;
    }
    getCodeBlockInfosForResponse(response) {
        const codeBlocks = this.codeBlocksByResponseId.get(response.id);
        return codeBlocks ?? [];
    }
    getCodeBlockInfoForEditor(uri) {
        return this.codeBlocksByEditorUri.get(uri);
    }
    getFileTreeInfosForResponse(response) {
        const fileTrees = this.fileTreesByResponseId.get(response.id);
        return fileTrees ?? [];
    }
    getLastFocusedFileTreeForResponse(response) {
        const fileTrees = this.fileTreesByResponseId.get(response.id);
        const lastFocusedFileTreeIndex = this.focusedFileTreesByResponseId.get(response.id);
        if (fileTrees?.length && lastFocusedFileTreeIndex !== undefined && lastFocusedFileTreeIndex < fileTrees.length) {
            return fileTrees[lastFocusedFileTreeIndex];
        }
        return undefined;
    }
    setVisible(visible) {
        this._isVisible = visible;
        this._onDidChangeVisibility.fire(visible);
    }
    layout(width) {
        this._currentLayoutWidth = width - (this.rendererOptions.noPadding ? 0 : 40);
        for (const editor of this._editorPool.inUse()) {
            editor.layout(this._currentLayoutWidth);
        }
    }
    renderTemplate(container) {
        const templateDisposables = ( (new DisposableStore()));
        const rowContainer = append(container, $('.interactive-item-container'));
        if (this.rendererOptions.renderStyle === 'compact') {
            rowContainer.classList.add('interactive-item-compact');
        }
        if (this.rendererOptions.noPadding) {
            rowContainer.classList.add('no-padding');
        }
        const header = append(rowContainer, $('.header'));
        const user = append(header, $('.user'));
        const avatarContainer = append(user, $('.avatar-container'));
        const agentAvatarContainer = append(user, $('.agent-avatar-container'));
        const username = append(user, $('h3.username'));
        const detailContainer = append(user, $('span.detail-container'));
        const detail = append(detailContainer, $('span.detail'));
        append(detailContainer, $('span.chat-animated-ellipsis'));
        const referencesListContainer = append(rowContainer, $('.referencesListContainer'));
        const value = append(rowContainer, $('.value'));
        const elementDisposables = ( (new DisposableStore()));
        const contextKeyService = templateDisposables.add(this.contextKeyService.createScoped(rowContainer));
        const scopedInstantiationService = this.instantiationService.createChild(( (new ServiceCollection([IContextKeyService, contextKeyService]))));
        let titleToolbar;
        if (this.rendererOptions.noHeader) {
            header.classList.add('hidden');
        }
        else {
            titleToolbar = templateDisposables.add(scopedInstantiationService.createInstance(MenuWorkbenchToolBar, header, MenuId.ChatMessageTitle, {
                menuOptions: {
                    shouldForwardArgs: true
                },
                toolbarOptions: {
                    shouldInlineSubmenu: submenu => submenu.actions.length <= 1
                },
                actionViewItemProvider: (action, options) => {
                    if (action instanceof MenuItemAction && (action.item.id === 'workbench.action.chat.voteDown' || action.item.id === 'workbench.action.chat.voteUp')) {
                        return scopedInstantiationService.createInstance(ChatVoteButton, action, options);
                    }
                    return createActionViewItem(scopedInstantiationService, action, options);
                }
            }));
        }
        const template = { avatarContainer, agentAvatarContainer, username, detail, referencesListContainer, value, rowContainer, elementDisposables, titleToolbar, templateDisposables, contextKeyService };
        return template;
    }
    renderElement(node, index, templateData) {
        this.renderChatTreeItem(node.element, index, templateData);
    }
    renderChatTreeItem(element, index, templateData) {
        const kind = isRequestVM(element) ? 'request' :
            isResponseVM(element) ? 'response' :
                'welcome';
        this.traceLayout('renderElement', `${kind}, index=${index}`);
        CONTEXT_RESPONSE.bindTo(templateData.contextKeyService).set(isResponseVM(element));
        CONTEXT_REQUEST.bindTo(templateData.contextKeyService).set(isRequestVM(element));
        CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND.bindTo(templateData.contextKeyService).set(isResponseVM(element) && element.agentOrSlashCommandDetected);
        if (isResponseVM(element)) {
            CONTEXT_CHAT_RESPONSE_SUPPORT_ISSUE_REPORTING.bindTo(templateData.contextKeyService).set(!!element.agent?.metadata.supportIssueReporting);
            CONTEXT_RESPONSE_VOTE.bindTo(templateData.contextKeyService).set(element.vote === InteractiveSessionVoteDirection.Up ? 'up' : element.vote === InteractiveSessionVoteDirection.Down ? 'down' : '');
        }
        else {
            CONTEXT_RESPONSE_VOTE.bindTo(templateData.contextKeyService).set('');
        }
        if (templateData.titleToolbar) {
            templateData.titleToolbar.context = element;
        }
        const isFiltered = !!(isResponseVM(element) && element.errorDetails?.responseIsFiltered);
        CONTEXT_RESPONSE_FILTERED.bindTo(templateData.contextKeyService).set(isFiltered);
        templateData.rowContainer.classList.toggle('interactive-request', isRequestVM(element));
        templateData.rowContainer.classList.toggle('interactive-response', isResponseVM(element));
        templateData.rowContainer.classList.toggle('interactive-welcome', isWelcomeVM(element));
        templateData.rowContainer.classList.toggle('filtered-response', isFiltered);
        templateData.rowContainer.classList.toggle('show-detail-progress', isResponseVM(element) && !element.isComplete && !element.progressMessages.length);
        templateData.username.textContent = element.username;
        if (!this.rendererOptions.noHeader) {
            this.renderAvatar(element, templateData);
        }
        clearNode(templateData.detail);
        if (isResponseVM(element)) {
            this.renderDetail(element, templateData);
        }
        if (isResponseVM(element) && index === this.delegate.getListLength() - 1 && (!element.isComplete || element.renderData) && element.response.value.length) {
            this.traceLayout('renderElement', `start progressive render ${kind}, index=${index}`);
            const progressiveRenderingDisposables = templateData.elementDisposables.add(( (new DisposableStore())));
            const timer = templateData.elementDisposables.add(new WindowIntervalTimer());
            const runProgressiveRender = (initial) => {
                try {
                    if (this.doNextProgressiveRender(element, index, templateData, !!initial, progressiveRenderingDisposables)) {
                        timer.cancel();
                    }
                }
                catch (err) {
                    timer.cancel();
                    throw err;
                }
            };
            timer.cancelAndSet(runProgressiveRender, 50, getWindow(templateData.rowContainer));
            runProgressiveRender(true);
        }
        else if (isResponseVM(element)) {
            const renderableResponse = annotateSpecialMarkdownContent(element.response.value);
            this.basicRenderElement(renderableResponse, element, index, templateData);
        }
        else if (isRequestVM(element)) {
            const markdown = 'message' in element.message ?
                element.message.message :
                this.markdownDecorationsRenderer.convertParsedRequestToMarkdown(element.message);
            this.basicRenderElement([{ content: ( (new MarkdownString(markdown))), kind: 'markdownContent' }], element, index, templateData);
        }
        else {
            this.renderWelcomeMessage(element, templateData);
        }
    }
    renderDetail(element, templateData) {
        let progressMsg = '';
        if (element.agent && !element.agent.isDefault) {
            let usingMsg = chatAgentLeader + element.agent.name;
            if (element.slashCommand) {
                usingMsg += ` ${chatSubcommandLeader}${element.slashCommand.name}`;
            }
            if (element.isComplete) {
                progressMsg = ( localizeWithPath(_moduleId, 0, "used {0}", usingMsg));
            }
            else {
                progressMsg = ( localizeWithPath(_moduleId, 1, "using {0}", usingMsg));
            }
        }
        else if (element.agentOrSlashCommandDetected) {
            const usingMsg = [];
            if (element.agent && !element.agent.isDefault) {
                usingMsg.push(chatAgentLeader + element.agent.name);
            }
            if (element.slashCommand) {
                usingMsg.push(chatSubcommandLeader + element.slashCommand.name);
            }
            if (usingMsg.length) {
                if (element.isComplete) {
                    progressMsg = ( localizeWithPath(_moduleId, 0, "used {0}", usingMsg.join(' ')));
                }
                else {
                    progressMsg = ( localizeWithPath(_moduleId, 1, "using {0}", usingMsg.join(' ')));
                }
            }
        }
        else if (!element.isComplete) {
            progressMsg = GeneratingPhrase;
        }
        templateData.detail.textContent = progressMsg;
        if (element.agent) {
            templateData.detail.title = progressMsg + (element.slashCommand?.description ? `\n${element.slashCommand.description}` : '');
        }
        else {
            templateData.detail.title = '';
        }
    }
    renderAvatar(element, templateData) {
        if (URI.isUri(element.avatarIcon)) {
            const avatarImgIcon = $$1('img.icon');
            avatarImgIcon.src = ( (FileAccess.uriToBrowserUri(element.avatarIcon).toString(true)));
            templateData.avatarContainer.replaceChildren($$1('.avatar', undefined, avatarImgIcon));
        }
        else {
            const defaultIcon = isRequestVM(element) ? Codicon.account : Codicon.copilot;
            const icon = element.avatarIcon ?? defaultIcon;
            const avatarIcon = $$1(ThemeIcon.asCSSSelector(icon));
            templateData.avatarContainer.replaceChildren($$1('.avatar.codicon-avatar', undefined, avatarIcon));
        }
        if (isResponseVM(element) && element.agent && !element.agent.isDefault) {
            show(templateData.agentAvatarContainer);
            const icon = this.getAgentIcon(element.agent.metadata);
            if (icon instanceof URI) {
                const avatarIcon = $$1('img.icon');
                avatarIcon.src = ( (FileAccess.uriToBrowserUri(icon).toString(true)));
                templateData.agentAvatarContainer.replaceChildren($$1('.avatar', undefined, avatarIcon));
            }
            else if (icon) {
                const avatarIcon = $$1(ThemeIcon.asCSSSelector(icon));
                templateData.agentAvatarContainer.replaceChildren($$1('.avatar.codicon-avatar', undefined, avatarIcon));
            }
            else {
                hide(templateData.agentAvatarContainer);
                return;
            }
            templateData.agentAvatarContainer.classList.toggle('complete', element.isComplete);
            if (!element.agentAvatarHasBeenRendered && !element.isComplete) {
                element.agentAvatarHasBeenRendered = true;
                templateData.agentAvatarContainer.classList.remove('loading');
                templateData.elementDisposables.add(disposableTimeout(() => {
                    templateData.agentAvatarContainer.classList.toggle('loading', !element.isComplete);
                }, 100));
            }
            else {
                templateData.agentAvatarContainer.classList.toggle('loading', !element.isComplete);
            }
        }
        else {
            hide(templateData.agentAvatarContainer);
        }
    }
    getAgentIcon(agent) {
        if (agent.themeIcon) {
            return agent.themeIcon;
        }
        else {
            return this.themeService.getColorTheme().type === ColorScheme.DARK && agent.iconDark ? agent.iconDark :
                agent.icon;
        }
    }
    basicRenderElement(value, element, index, templateData) {
        const fillInIncompleteTokens = isResponseVM(element) && (!element.isComplete || element.isCanceled || element.errorDetails?.responseIsFiltered || element.errorDetails?.responseIsIncomplete);
        clearNode(templateData.value);
        clearNode(templateData.referencesListContainer);
        if (isResponseVM(element)) {
            this.renderDetail(element, templateData);
        }
        this.renderContentReferencesIfNeeded(element, templateData, templateData.elementDisposables);
        let fileTreeIndex = 0;
        value.forEach((data, index) => {
            const result = data.kind === 'treeData'
                ? this.renderTreeData(data.treeData, element, templateData, fileTreeIndex++)
                : data.kind === 'markdownContent'
                    ? this.renderMarkdown(data.content, element, templateData, fillInIncompleteTokens)
                    : data.kind === 'progressMessage' && onlyProgressMessagesAfterI(value, index) ? this.renderProgressMessage(data, false)
                        : data.kind === 'command' ? this.renderCommandButton(element, data)
                            : undefined;
            if (result) {
                templateData.value.appendChild(result.element);
                templateData.elementDisposables.add(result);
            }
        });
        if (isResponseVM(element) && element.errorDetails?.message) {
            const icon = element.errorDetails.responseIsFiltered ? Codicon.info : Codicon.error;
            const errorDetails = append(templateData.value, $('.interactive-response-error-details', undefined, renderIcon(icon)));
            const renderedError = templateData.elementDisposables.add(this.renderer.render(( (new MarkdownString(element.errorDetails.message)))));
            errorDetails.appendChild($('span', undefined, renderedError.element));
        }
        if (isResponseVM(element) && element.isComplete && element.response.value.length === 0) {
            let madeChanges = false;
            for (const item of ( (element.edits.values()))) {
                if (item.length > 0) {
                    madeChanges = true;
                    break;
                }
            }
            if (madeChanges) {
                append(templateData.value, $('.interactive-edits-summary', undefined, ( localizeWithPath(_moduleId, 2, "Made changes."))));
            }
        }
        const newHeight = templateData.rowContainer.offsetHeight;
        const fireEvent = !element.currentRenderedHeight || element.currentRenderedHeight !== newHeight;
        element.currentRenderedHeight = newHeight;
        if (fireEvent) {
            const disposable = templateData.elementDisposables.add(scheduleAtNextAnimationFrame(getWindow(templateData.value), () => {
                disposable.dispose();
                this._onDidChangeItemHeight.fire({ element, height: newHeight });
            }));
        }
    }
    renderWelcomeMessage(element, templateData) {
        clearNode(templateData.value);
        clearNode(templateData.referencesListContainer);
        hide(templateData.referencesListContainer);
        for (const item of element.content) {
            if (Array.isArray(item)) {
                const scopedInstaService = this.instantiationService.createChild(( (new ServiceCollection([IContextKeyService, templateData.contextKeyService]))));
                templateData.elementDisposables.add(scopedInstaService.createInstance(ChatFollowups, templateData.value, item, this.location, undefined, followup => this._onDidClickFollowup.fire(followup)));
            }
            else {
                const result = this.renderMarkdown(item, element, templateData);
                templateData.value.appendChild(result.element);
                templateData.elementDisposables.add(result);
            }
        }
        const newHeight = templateData.rowContainer.offsetHeight;
        const fireEvent = !element.currentRenderedHeight || element.currentRenderedHeight !== newHeight;
        element.currentRenderedHeight = newHeight;
        if (fireEvent) {
            const disposable = templateData.elementDisposables.add(scheduleAtNextAnimationFrame(getWindow(templateData.value), () => {
                disposable.dispose();
                this._onDidChangeItemHeight.fire({ element, height: newHeight });
            }));
        }
    }
    doNextProgressiveRender(element, index, templateData, isInRenderElement, disposables) {
        if (!this._isVisible) {
            return true;
        }
        const renderableResponse = annotateSpecialMarkdownContent(element.response.value);
        let isFullyRendered = false;
        if (element.isCanceled) {
            this.traceLayout('runProgressiveRender', `canceled, index=${index}`);
            element.renderData = undefined;
            this.basicRenderElement(renderableResponse, element, index, templateData);
            isFullyRendered = true;
        }
        else {
            element.renderData ??= { renderedParts: [] };
            const renderedParts = element.renderData.renderedParts;
            const wordCountResults = [];
            const partsToRender = [];
            let somePartIsNotFullyRendered = false;
            renderableResponse.forEach((part, index) => {
                const renderedPart = renderedParts[index];
                if (!renderedPart) {
                    if (part.kind === 'treeData') {
                        partsToRender[index] = part.treeData;
                    }
                    else if (part.kind === 'progressMessage') {
                        partsToRender[index] = {
                            progressMessage: part,
                            isAtEndOfResponse: onlyProgressMessagesAfterI(renderableResponse, index),
                            isLast: index === renderableResponse.length - 1,
                        };
                    }
                    else if (part.kind === 'command') {
                        partsToRender[index] = part;
                    }
                    else {
                        const wordCountResult = this.getDataForProgressiveRender(element, contentToMarkdown(part.content), { renderedWordCount: 0, lastRenderTime: 0 });
                        if (wordCountResult !== undefined) {
                            this.traceLayout('doNextProgressiveRender', `Rendering new part ${index}, wordCountResult=${wordCountResult.actualWordCount}, rate=${wordCountResult.rate}`);
                            partsToRender[index] = {
                                renderedWordCount: wordCountResult.actualWordCount,
                                lastRenderTime: Date.now(),
                                isFullyRendered: wordCountResult.isFullString,
                            };
                            wordCountResults[index] = wordCountResult;
                        }
                    }
                }
                else if ((part.kind === 'markdownContent' || part.kind === 'progressMessage') && isMarkdownRenderData(renderedPart)) {
                    const wordCountResult = this.getDataForProgressiveRender(element, contentToMarkdown(part.content), renderedPart);
                    if (wordCountResult !== undefined && renderedPart.renderedWordCount !== wordCountResult?.actualWordCount) {
                        this.traceLayout('doNextProgressiveRender', `Rendering changed part ${index}, wordCountResult=${wordCountResult.actualWordCount}, rate=${wordCountResult.rate}`);
                        partsToRender[index] = {
                            renderedWordCount: wordCountResult.actualWordCount,
                            lastRenderTime: Date.now(),
                            isFullyRendered: wordCountResult.isFullString,
                        };
                        wordCountResults[index] = wordCountResult;
                    }
                    else if (!renderedPart.isFullyRendered && !wordCountResult) {
                        somePartIsNotFullyRendered = true;
                    }
                }
                else if (part.kind === 'progressMessage' && isProgressMessageRenderData(renderedPart) && ((renderedPart.isAtEndOfResponse !== onlyProgressMessagesAfterI(renderableResponse, index)) ||
                    renderedPart.isLast !== (index === renderableResponse.length - 1))) {
                    partsToRender[index] = {
                        progressMessage: part,
                        isAtEndOfResponse: onlyProgressMessagesAfterI(renderableResponse, index),
                        isLast: index === renderableResponse.length - 1,
                    };
                }
            });
            isFullyRendered = partsToRender.length === 0 && !somePartIsNotFullyRendered;
            if (isFullyRendered && element.isComplete) {
                this.traceLayout('runProgressiveRender', `end progressive render, index=${index} and clearing renderData, response is complete, index=${index}`);
                element.renderData = undefined;
                disposables.clear();
                this.basicRenderElement(renderableResponse, element, index, templateData);
            }
            else if (!isFullyRendered) {
                disposables.clear();
                this.renderContentReferencesIfNeeded(element, templateData, disposables);
                let hasRenderedOneMarkdownBlock = false;
                partsToRender.forEach((partToRender, index) => {
                    if (!partToRender) {
                        return;
                    }
                    let result;
                    if (isInteractiveProgressTreeData(partToRender)) {
                        result = this.renderTreeData(partToRender, element, templateData, index);
                    }
                    else if (isProgressMessageRenderData(partToRender)) {
                        if (onlyProgressMessageRenderDatasAfterI(partsToRender, index)) {
                            result = this.renderProgressMessage(partToRender.progressMessage, index === partsToRender.length - 1);
                        }
                        else {
                            result = null;
                        }
                    }
                    else if (isCommandButtonRenderData(partToRender)) {
                        result = this.renderCommandButton(element, partToRender);
                    }
                    else if (!hasRenderedOneMarkdownBlock && wordCountResults[index]) {
                        const { value } = wordCountResults[index];
                        result = this.renderMarkdown(( (new MarkdownString(value))), element, templateData, true);
                        hasRenderedOneMarkdownBlock = true;
                    }
                    if (result === undefined) {
                        return;
                    }
                    renderedParts[index] = partToRender;
                    const existingElement = templateData.value.children[index];
                    if (existingElement) {
                        if (result === null) {
                            templateData.value.replaceChild($('span.placeholder-for-deleted-thing'), existingElement);
                        }
                        else {
                            templateData.value.replaceChild(result.element, existingElement);
                        }
                    }
                    else if (result) {
                        templateData.value.appendChild(result.element);
                    }
                    if (result) {
                        disposables.add(result);
                    }
                });
            }
            else {
                return false;
            }
        }
        const height = templateData.rowContainer.offsetHeight;
        element.currentRenderedHeight = height;
        if (!isInRenderElement) {
            this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight });
        }
        return isFullyRendered;
    }
    renderTreeData(data, element, templateData, treeDataIndex) {
        const treeDisposables = ( (new DisposableStore()));
        const ref = treeDisposables.add(this._treePool.get());
        const tree = ref.object;
        treeDisposables.add(tree.onDidOpen((e) => {
            if (e.element && !('children' in e.element)) {
                this.openerService.open(e.element.uri);
            }
        }));
        treeDisposables.add(tree.onDidChangeCollapseState(() => {
            this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight });
        }));
        treeDisposables.add(tree.onContextMenu((e) => {
            e.browserEvent.preventDefault();
            e.browserEvent.stopPropagation();
        }));
        tree.setInput(data).then(() => {
            if (!ref.isStale()) {
                tree.layout();
                this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight });
            }
        });
        if (isResponseVM(element)) {
            const fileTreeFocusInfo = {
                treeDataId: ( (data.uri.toString())),
                treeIndex: treeDataIndex,
                focus() {
                    tree.domFocus();
                }
            };
            treeDisposables.add(tree.onDidFocus(() => {
                this.focusedFileTreesByResponseId.set(element.id, fileTreeFocusInfo.treeIndex);
            }));
            const fileTrees = this.fileTreesByResponseId.get(element.id) ?? [];
            fileTrees.push(fileTreeFocusInfo);
            this.fileTreesByResponseId.set(element.id, distinct(fileTrees, (v) => v.treeDataId));
            treeDisposables.add(toDisposable(() => this.fileTreesByResponseId.set(element.id, fileTrees.filter(v => v.treeDataId !== ( (data.uri.toString()))))));
        }
        return {
            element: tree.getHTMLElement().parentElement,
            dispose: () => {
                treeDisposables.dispose();
            }
        };
    }
    renderContentReferencesIfNeeded(element, templateData, disposables) {
        clearNode(templateData.referencesListContainer);
        if (isResponseVM(element) && this._usedReferencesEnabled && element.contentReferences.length) {
            show(templateData.referencesListContainer);
            const contentReferencesListResult = this.renderContentReferencesListData(element.contentReferences, element, templateData);
            templateData.referencesListContainer.appendChild(contentReferencesListResult.element);
            disposables.add(contentReferencesListResult);
        }
        else {
            hide(templateData.referencesListContainer);
        }
    }
    renderContentReferencesListData(data, element, templateData) {
        const listDisposables = ( (new DisposableStore()));
        const referencesLabel = data.length > 1 ?
            ( localizeWithPath(_moduleId, 3, "Used {0} references", data.length)) :
            ( localizeWithPath(_moduleId, 4, "Used {0} reference", 1));
        const iconElement = $('.chat-used-context-icon');
        const icon = (element) => element.usedReferencesExpanded ? Codicon.chevronDown : Codicon.chevronRight;
        iconElement.classList.add(...ThemeIcon.asClassNameArray(icon(element)));
        const buttonElement = $('.chat-used-context-label', undefined);
        const collapseButton = listDisposables.add(( (new Button(buttonElement, {
            buttonBackground: undefined,
            buttonBorder: undefined,
            buttonForeground: undefined,
            buttonHoverBackground: undefined,
            buttonSecondaryBackground: undefined,
            buttonSecondaryForeground: undefined,
            buttonSecondaryHoverBackground: undefined,
            buttonSeparator: undefined
        }))));
        const container = $('.chat-used-context', undefined, buttonElement);
        collapseButton.label = referencesLabel;
        collapseButton.element.append(iconElement);
        this.updateAriaLabel(collapseButton.element, referencesLabel, element.usedReferencesExpanded);
        container.classList.toggle('chat-used-context-collapsed', !element.usedReferencesExpanded);
        listDisposables.add(collapseButton.onDidClick(() => {
            iconElement.classList.remove(...ThemeIcon.asClassNameArray(icon(element)));
            element.usedReferencesExpanded = !element.usedReferencesExpanded;
            iconElement.classList.add(...ThemeIcon.asClassNameArray(icon(element)));
            container.classList.toggle('chat-used-context-collapsed', !element.usedReferencesExpanded);
            this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight });
            this.updateAriaLabel(collapseButton.element, referencesLabel, element.usedReferencesExpanded);
        }));
        const ref = listDisposables.add(this._contentReferencesListPool.get());
        const list = ref.object;
        container.appendChild(list.getHTMLElement().parentElement);
        listDisposables.add(list.onDidOpen((e) => {
            if (e.element) {
                const uriOrLocation = 'variableName' in e.element.reference ? e.element.reference.value : e.element.reference;
                const uri = URI.isUri(uriOrLocation) ? uriOrLocation :
                    uriOrLocation?.uri;
                if (uri) {
                    this.openerService.open(uri, {
                        fromUserGesture: true,
                        editorOptions: {
                            ...e.editorOptions,
                            ...{
                                selection: uriOrLocation && 'range' in uriOrLocation ? uriOrLocation.range : undefined
                            }
                        }
                    });
                }
            }
        }));
        listDisposables.add(list.onContextMenu((e) => {
            e.browserEvent.preventDefault();
            e.browserEvent.stopPropagation();
        }));
        const maxItemsShown = 6;
        const itemsShown = Math.min(data.length, maxItemsShown);
        const height = itemsShown * 22;
        list.layout(height);
        list.getHTMLElement().style.height = `${height}px`;
        list.splice(0, list.length, data);
        return {
            element: container,
            dispose: () => {
                listDisposables.dispose();
            }
        };
    }
    updateAriaLabel(element, label, expanded) {
        element.ariaLabel = expanded ? ( localizeWithPath(_moduleId, 5, "{0}, expanded", label)) : ( localizeWithPath(_moduleId, 6, "{0}, collapsed", label));
    }
    renderProgressMessage(progress, showSpinner) {
        if (showSpinner) {
            alert(progress.content.value);
        }
        const codicon = showSpinner ? ThemeIcon.modify(Codicon.sync, 'spin').id : Codicon.check.id;
        const markdown = ( (new MarkdownString(`$(${codicon}) ${progress.content.value}`, {
            supportThemeIcons: true
        })));
        const result = this.renderer.render(markdown);
        result.element.classList.add('progress-step');
        return result;
    }
    renderCommandButton(element, commandButton) {
        const container = $('.chat-command-button');
        const disposables = ( (new DisposableStore()));
        const enabled = !isResponseVM(element) || !element.isStale;
        const tooltip = enabled ?
            commandButton.command.tooltip :
            ( localizeWithPath(_moduleId, 7, "Button not available in restored chat"));
        const button = disposables.add(( (new Button(container, { ...defaultButtonStyles, supportIcons: true, title: tooltip }))));
        button.label = commandButton.command.title;
        button.enabled = enabled;
        disposables.add(button.onDidClick(() => this.commandService.executeCommand(commandButton.command.id, ...(commandButton.command.arguments ?? []))));
        return {
            dispose() {
                disposables.dispose();
            },
            element: container
        };
    }
    renderMarkdown(markdown, element, templateData, fillInIncompleteTokens = false) {
        const disposables = ( (new DisposableStore()));
        markdown = ( (new MarkdownString(markdown.value, {
            isTrusted: {
                enabledCommands: typeof markdown.isTrusted === 'object' ? markdown.isTrusted?.enabledCommands : [] ?? []
            }
        })));
        const orderedDisposablesList = [];
        const codeblocks = [];
        let codeBlockIndex = 0;
        const result = this.renderer.render(markdown, {
            fillInIncompleteTokens,
            codeBlockRendererSync: (languageId, text) => {
                const index = codeBlockIndex++;
                let textModel;
                let range;
                let vulns;
                if (equalsIgnoreCase(languageId, localFileLanguageId)) {
                    try {
                        const parsedBody = parseLocalFileData(text);
                        range = parsedBody.range && Range.lift(parsedBody.range);
                        textModel = this.textModelService.createModelReference(parsedBody.uri).then(ref => ref.object);
                    }
                    catch (e) {
                        return $('div');
                    }
                }
                else {
                    if (!isRequestVM(element) && !isResponseVM(element)) {
                        console.error('Trying to render code block in welcome', element.id, index);
                        return $('div');
                    }
                    const sessionId = isResponseVM(element) || isRequestVM(element) ? element.sessionId : '';
                    const modelEntry = this.codeBlockModelCollection.getOrCreate(sessionId, element, index);
                    vulns = modelEntry.vulns;
                    textModel = modelEntry.model;
                }
                const hideToolbar = isResponseVM(element) && element.errorDetails?.responseIsFiltered;
                const ref = this.renderCodeBlock({ languageId, textModel, codeBlockIndex: index, element, range, hideToolbar, parentContextKeyService: templateData.contextKeyService, vulns }, text);
                disposables.add(ref.object.onDidChangeContentHeight(() => {
                    ref.object.layout(this._currentLayoutWidth);
                    this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight });
                }));
                if (isResponseVM(element)) {
                    const info = {
                        codeBlockIndex: index,
                        element,
                        focus() {
                            ref.object.focus();
                        }
                    };
                    codeblocks.push(info);
                    if (ref.object.uri) {
                        const uri = ref.object.uri;
                        this.codeBlocksByEditorUri.set(uri, info);
                        disposables.add(toDisposable(() => this.codeBlocksByEditorUri.delete(uri)));
                    }
                }
                orderedDisposablesList.push(ref);
                return ref.object.element;
            },
            asyncRenderCallback: () => this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight }),
        });
        if (isResponseVM(element)) {
            this.codeBlocksByResponseId.set(element.id, codeblocks);
            disposables.add(toDisposable(() => this.codeBlocksByResponseId.delete(element.id)));
        }
        this.markdownDecorationsRenderer.walkTreeAndAnnotateReferenceLinks(result.element);
        orderedDisposablesList.reverse().forEach(d => disposables.add(d));
        return {
            element: result.element,
            dispose() {
                result.dispose();
                disposables.dispose();
            }
        };
    }
    renderCodeBlock(data, text) {
        const ref = this._editorPool.get();
        const editorInfo = ref.object;
        if (isResponseVM(data.element)) {
            this.codeBlockModelCollection.update(data.element.sessionId, data.element, data.codeBlockIndex, { text, languageId: data.languageId });
        }
        editorInfo.render(data, this._currentLayoutWidth, this.rendererOptions.editableCodeBlock);
        return ref;
    }
    getDataForProgressiveRender(element, data, renderData) {
        const rate = this.getProgressiveRenderRate(element);
        const numWordsToRender = renderData.lastRenderTime === 0 ?
            1 :
            renderData.renderedWordCount +
                Math.floor((Date.now() - renderData.lastRenderTime) / 1000 * rate);
        if (numWordsToRender === renderData.renderedWordCount) {
            return undefined;
        }
        return {
            ...getNWords(data.value, numWordsToRender),
            rate
        };
    }
    disposeElement(node, index, templateData) {
        templateData.elementDisposables.clear();
    }
    disposeTemplate(templateData) {
        templateData.templateDisposables.dispose();
    }
};
ChatListItemRenderer = ChatListItemRenderer_1 = ( (__decorate([
    ( (__param(6, IInstantiationService))),
    ( (__param(7, IConfigurationService))),
    ( (__param(8, ILogService))),
    ( (__param(9, IOpenerService))),
    ( (__param(10, IContextKeyService))),
    ( (__param(11, IThemeService))),
    ( (__param(12, ICommandService))),
    ( (__param(13, ITextModelService)))
], ChatListItemRenderer)));
let ChatListDelegate = class ChatListDelegate {
    constructor(defaultElementHeight, logService) {
        this.defaultElementHeight = defaultElementHeight;
        this.logService = logService;
    }
    _traceLayout(method, message) {
        {
            this.logService.trace(`ChatListDelegate#${method}: ${message}`);
        }
    }
    getHeight(element) {
        const kind = isRequestVM(element) ? 'request' : 'response';
        const height = ('currentRenderedHeight' in element ? element.currentRenderedHeight : undefined) ?? this.defaultElementHeight;
        this._traceLayout('getHeight', `${kind}, height=${height}`);
        return height;
    }
    getTemplateId(element) {
        return ChatListItemRenderer.ID;
    }
    hasDynamicHeight(element) {
        return true;
    }
};
ChatListDelegate = ( (__decorate([
    ( (__param(1, ILogService)))
], ChatListDelegate)));
let EditorPool = class EditorPool extends Disposable {
    inUse() {
        return this._pool.inUse;
    }
    constructor(options, delegate, overflowWidgetsDomNode, instantiationService) {
        super();
        this._pool = this._register(( (new ResourcePool(() => {
            return instantiationService.createInstance(CodeBlockPart, options, MenuId.ChatCodeBlock, delegate, overflowWidgetsDomNode);
        }))));
    }
    get() {
        const codeBlock = this._pool.get();
        let stale = false;
        return {
            object: codeBlock,
            isStale: () => stale,
            dispose: () => {
                codeBlock.reset();
                stale = true;
                this._pool.release(codeBlock);
            }
        };
    }
};
EditorPool = ( (__decorate([
    ( (__param(3, IInstantiationService)))
], EditorPool)));
let TreePool = class TreePool extends Disposable {
    get inUse() {
        return this._pool.inUse;
    }
    constructor(_onDidChangeVisibility, instantiationService, configService, themeService) {
        super();
        this._onDidChangeVisibility = _onDidChangeVisibility;
        this.instantiationService = instantiationService;
        this.configService = configService;
        this.themeService = themeService;
        this._pool = this._register(( (new ResourcePool(() => this.treeFactory()))));
    }
    treeFactory() {
        const resourceLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this._onDidChangeVisibility });
        const container = $('.interactive-response-progress-tree');
        this._register(createFileIconThemableTreeContainerScope(container, this.themeService));
        const tree = this.instantiationService.createInstance(WorkbenchCompressibleAsyncDataTree, 'ChatListRenderer', container, ( (new ChatListTreeDelegate())), ( (new ChatListTreeCompressionDelegate())), [( (new ChatListTreeRenderer(resourceLabels, this.configService.getValue('explorer.decorations'))))], ( (new ChatListTreeDataSource())), {
            collapseByDefault: () => false,
            expandOnlyOnTwistieClick: () => false,
            identityProvider: {
                getId: (e) => ( (e.uri.toString()))
            },
            accessibilityProvider: {
                getAriaLabel: (element) => element.label,
                getWidgetAriaLabel: () => ( localizeWithPath(_moduleId, 8, "File Tree"))
            },
            alwaysConsumeMouseWheel: false
        });
        return tree;
    }
    get() {
        const object = this._pool.get();
        let stale = false;
        return {
            object,
            isStale: () => stale,
            dispose: () => {
                stale = true;
                this._pool.release(object);
            }
        };
    }
};
TreePool = ( (__decorate([
    ( (__param(1, IInstantiationService))),
    ( (__param(2, IConfigurationService))),
    ( (__param(3, IThemeService)))
], TreePool)));
let ContentReferencesListPool = class ContentReferencesListPool extends Disposable {
    get inUse() {
        return this._pool.inUse;
    }
    constructor(_onDidChangeVisibility, instantiationService, themeService) {
        super();
        this._onDidChangeVisibility = _onDidChangeVisibility;
        this.instantiationService = instantiationService;
        this.themeService = themeService;
        this._pool = this._register(( (new ResourcePool(() => this.listFactory()))));
    }
    listFactory() {
        const resourceLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this._onDidChangeVisibility });
        const container = $('.chat-used-context-list');
        this._register(createFileIconThemableTreeContainerScope(container, this.themeService));
        const list = this.instantiationService.createInstance(WorkbenchList, 'ChatListRenderer', container, ( (new ContentReferencesListDelegate())), [this.instantiationService.createInstance(ContentReferencesListRenderer, resourceLabels)], {
            alwaysConsumeMouseWheel: false,
            accessibilityProvider: {
                getAriaLabel: (element) => {
                    const reference = element.reference;
                    if ('variableName' in reference) {
                        return reference.variableName;
                    }
                    else if (URI.isUri(reference)) {
                        return basename(reference.path);
                    }
                    else {
                        return basename(reference.uri.path);
                    }
                },
                getWidgetAriaLabel: () => ( localizeWithPath(_moduleId, 9, "Used References"))
            },
        });
        return list;
    }
    get() {
        const object = this._pool.get();
        let stale = false;
        return {
            object,
            isStale: () => stale,
            dispose: () => {
                stale = true;
                this._pool.release(object);
            }
        };
    }
};
ContentReferencesListPool = ( (__decorate([
    ( (__param(1, IInstantiationService))),
    ( (__param(2, IThemeService)))
], ContentReferencesListPool)));
class ContentReferencesListDelegate {
    getHeight(element) {
        return 22;
    }
    getTemplateId(element) {
        return ContentReferencesListRenderer.TEMPLATE_ID;
    }
}
let ContentReferencesListRenderer = class ContentReferencesListRenderer {
    static { ContentReferencesListRenderer_1 = this; }
    static { this.TEMPLATE_ID = 'contentReferencesListRenderer'; }
    constructor(labels, chatVariablesService) {
        this.labels = labels;
        this.chatVariablesService = chatVariablesService;
        this.templateId = ContentReferencesListRenderer_1.TEMPLATE_ID;
    }
    renderTemplate(container) {
        const templateDisposables = ( (new DisposableStore()));
        const label = templateDisposables.add(this.labels.create(container, { supportHighlights: true }));
        return { templateDisposables, label };
    }
    renderElement(data, index, templateData, height) {
        const reference = data.reference;
        templateData.label.element.style.display = 'flex';
        if ('variableName' in reference) {
            if (reference.value) {
                const uri = URI.isUri(reference.value) ? reference.value : reference.value.uri;
                templateData.label.setResource({
                    resource: uri,
                    name: basenameOrAuthority(uri),
                    description: `#${reference.variableName}`,
                    range: 'range' in reference.value ? reference.value.range : undefined
                });
            }
            else {
                const variable = this.chatVariablesService.getVariable(reference.variableName);
                templateData.label.setLabel(`#${reference.variableName}`, undefined, { title: variable?.description });
            }
        }
        else {
            const uri = 'uri' in reference ? reference.uri : reference;
            if (matchesSomeScheme(uri, Schemas.mailto, Schemas.http, Schemas.https)) {
                templateData.label.setResource({ resource: uri, name: ( (uri.toString())) }, { icon: Codicon.globe });
            }
            else {
                templateData.label.setFile(uri, {
                    fileKind: FileKind.FILE,
                    fileDecorations: { badges: false, colors: false },
                    range: 'range' in reference ? reference.range : undefined
                });
            }
        }
    }
    disposeTemplate(templateData) {
        templateData.templateDisposables.dispose();
    }
};
ContentReferencesListRenderer = ContentReferencesListRenderer_1 = ( (__decorate([
    ( (__param(1, IChatVariablesService)))
], ContentReferencesListRenderer)));
class ResourcePool extends Disposable {
    get inUse() {
        return this._inUse;
    }
    constructor(_itemFactory) {
        super();
        this._itemFactory = _itemFactory;
        this.pool = [];
        this._inUse = ( (new Set()));
    }
    get() {
        if (this.pool.length > 0) {
            const item = this.pool.pop();
            this._inUse.add(item);
            return item;
        }
        const item = this._register(this._itemFactory());
        this._inUse.add(item);
        return item;
    }
    release(item) {
        this._inUse.delete(item);
        this.pool.push(item);
    }
}
class ChatVoteButton extends MenuEntryActionViewItem {
    render(container) {
        super.render(container);
        container.classList.toggle('checked', this.action.checked);
    }
}
class ChatListTreeDelegate {
    static { this.ITEM_HEIGHT = 22; }
    getHeight(element) {
        return ChatListTreeDelegate.ITEM_HEIGHT;
    }
    getTemplateId(element) {
        return 'chatListTreeTemplate';
    }
}
class ChatListTreeCompressionDelegate {
    isIncompressible(element) {
        return !element.children;
    }
}
class ChatListTreeRenderer {
    constructor(labels, decorations) {
        this.labels = labels;
        this.decorations = decorations;
        this.templateId = 'chatListTreeTemplate';
    }
    renderCompressedElements(element, index, templateData, height) {
        templateData.label.element.style.display = 'flex';
        const label = ( (element.element.elements.map((e) => e.label)));
        templateData.label.setResource({ resource: element.element.elements[0].uri, name: label }, {
            title: element.element.elements[0].label,
            fileKind: element.children ? FileKind.FOLDER : FileKind.FILE,
            extraClasses: ['explorer-item'],
            fileDecorations: this.decorations
        });
    }
    renderTemplate(container) {
        const templateDisposables = ( (new DisposableStore()));
        const label = templateDisposables.add(this.labels.create(container, { supportHighlights: true }));
        return { templateDisposables, label };
    }
    renderElement(element, index, templateData, height) {
        templateData.label.element.style.display = 'flex';
        if (!element.children.length && element.element.type !== FileType.Directory) {
            templateData.label.setFile(element.element.uri, {
                fileKind: FileKind.FILE,
                hidePath: true,
                fileDecorations: this.decorations,
            });
        }
        else {
            templateData.label.setResource({ resource: element.element.uri, name: element.element.label }, {
                title: element.element.label,
                fileKind: FileKind.FOLDER,
                fileDecorations: this.decorations
            });
        }
    }
    disposeTemplate(templateData) {
        templateData.templateDisposables.dispose();
    }
}
class ChatListTreeDataSource {
    hasChildren(element) {
        return !!element.children;
    }
    async getChildren(element) {
        return element.children ?? [];
    }
}
function isInteractiveProgressTreeData(item) {
    return 'label' in item;
}
function contentToMarkdown(str) {
    return typeof str === 'string' ? { value: str } : str;
}
function isProgressMessage(item) {
    return item && 'kind' in item && item.kind === 'progressMessage';
}
function isProgressMessageRenderData(item) {
    return item && 'isAtEndOfResponse' in item;
}
function isCommandButtonRenderData(item) {
    return item && 'kind' in item && item.kind === 'command';
}
function isMarkdownRenderData(item) {
    return item && 'renderedWordCount' in item;
}
function onlyProgressMessagesAfterI(items, i) {
    return items.slice(i).every(isProgressMessage);
}
function onlyProgressMessageRenderDatasAfterI(items, i) {
    return items.slice(i).every(isProgressMessageRenderData);
}
export { ChatListDelegate, ChatListItemRenderer };
