/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var cleaner_exports = {};
__export(cleaner_exports, {
  CheckpointCleaner: () => CheckpointCleaner
});
module.exports = __toCommonJS(cleaner_exports);
var import_database = require("@nocobase/database");
class CheckpointCleaner {
  constructor(provideCollectionManager, checkpointSaver) {
    this.provideCollectionManager = provideCollectionManager;
    this.checkpointSaver = checkpointSaver;
  }
  async cleanOutdated(expiredAt) {
    const outdatedConversations = await this.aiConversationsModel.findAll({
      attributes: ["sessionId", "thread"],
      where: {
        updatedAt: {
          [import_database.Op.lt]: expiredAt
        },
        thread: {
          [import_database.Op.ne]: 0
        }
      },
      raw: true
    });
    if (!outdatedConversations.length) {
      return;
    }
    const sessionIds = outdatedConversations.map((conversation) => conversation.sessionId);
    const latestMessageRefs = await this.aiMessagesModel.findAll({
      attributes: ["sessionId", [this.sequelize.fn("MAX", this.sequelize.col("messageId")), "messageId"]],
      where: {
        sessionId: {
          [import_database.Op.in]: sessionIds
        }
      },
      group: ["sessionId"],
      raw: true
    });
    if (!latestMessageRefs.length) {
      return;
    }
    const latestMessageIds = latestMessageRefs.map((row) => row.messageId);
    const latestMessages = await this.aiMessagesModel.findAll({
      attributes: ["sessionId", "updatedAt", "toolCalls"],
      where: {
        messageId: {
          [import_database.Op.in]: latestMessageIds
        }
      },
      raw: true
    });
    const latestMessageMap = new Map(latestMessages.map((message) => [message.sessionId, message]));
    const conversationsToClean = [];
    for (const conversation of outdatedConversations) {
      const latestMessage = latestMessageMap.get(conversation.sessionId);
      if (!latestMessage) {
        continue;
      }
      const latestMessageAt = latestMessage.updatedAt ? new Date(latestMessage.updatedAt) : void 0;
      const hasToolCalls = Array.isArray(latestMessage.toolCalls) ? latestMessage.toolCalls.length > 0 : !!latestMessage.toolCalls;
      if (latestMessageAt && latestMessageAt < expiredAt && !hasToolCalls) {
        conversationsToClean.push(conversation);
      }
    }
    if (!conversationsToClean.length) {
      return;
    }
    await this.clean(conversationsToClean);
  }
  async clean(conversations) {
    if (!(conversations == null ? void 0 : conversations.length)) {
      return;
    }
    const threadIds = this.getThreadIds(conversations);
    await this.aiConversationsModel.update(
      { thread: 0 },
      {
        where: {
          sessionId: {
            [import_database.Op.in]: conversations.map((x) => x.sessionId)
          }
        }
      }
    );
    for (const threadId of threadIds) {
      await this.checkpointSaver.deleteThread(threadId);
    }
  }
  getThreadIds(conversations) {
    const threadIds = [];
    for (const conversation of conversations) {
      for (let i = conversation.thread; i > 0; i--) {
        threadIds.push(`${conversation.sessionId}:${i}`);
      }
    }
    return threadIds;
  }
  get aiConversationsModel() {
    return this.collectionManager.getCollection("aiConversations").model;
  }
  get aiMessagesModel() {
    return this.collectionManager.getCollection("aiMessages").model;
  }
  get sequelize() {
    return this.collectionManager.db.sequelize;
  }
  get collectionManager() {
    return this.provideCollectionManager().collectionManager;
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  CheckpointCleaner
});
