/**
 * 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 __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var plugin_exports = {};
__export(plugin_exports, {
  PluginAIServer: () => PluginAIServer,
  default: () => plugin_default
});
module.exports = __toCommonJS(plugin_exports);
var import_server = require("@nocobase/server");
var import_ai_manager = require("./manager/ai-manager");
var import_ai_feature_manager = require("./manager/ai-feature-manager");
var import_openai = require("./llm-providers/openai");
var import_openai2 = require("./llm-providers/openai");
var import_deepseek = require("./llm-providers/deepseek");
var import_ai = __toESM(require("./resource/ai"));
var import_llm = require("./workflow/nodes/llm");
var import_aiConversations = __toESM(require("./resource/aiConversations"));
var import_aiTools = __toESM(require("./resource/aiTools"));
var import_ai_employees_manager = require("./ai-employees/ai-employees-manager");
var import_snowflake = __toESM(require("./snowflake"));
var aiEmployeeActions = __toESM(require("./resource/aiEmployees"));
var import_google_genai = require("./llm-providers/google-genai");
var import_ai_employee = require("./workflow/triggers/ai-employee");
var import_tools = require("./tools");
var import_anthropic = require("./llm-providers/anthropic");
var import_aiSettings = __toESM(require("./resource/aiSettings"));
var import_dashscope = require("./llm-providers/dashscope");
var import_ollama = require("./llm-providers/ollama");
var import_built_in_manager = require("./manager/built-in-manager");
var import_ai_context_datasource_manager = require("./manager/ai-context-datasource-manager");
var import_aiContextDatasources = require("./resource/aiContextDatasources");
var import_work_context_handler = require("./manager/work-context-handler");
var import_ai_coding_manager = require("./manager/ai-coding-manager");
var import_kimi = require("./llm-providers/kimi");
var import_document_loader = require("./document-loader");
var import_checkpoints = require("./ai-employees/checkpoints");
class PluginAIServer extends import_server.Plugin {
  features = new import_ai_feature_manager.AIPluginFeatureManagerImpl();
  aiManager = new import_ai_manager.AIManager(this);
  aiEmployeesManager = new import_ai_employees_manager.AIEmployeesManager(this);
  builtInManager = new import_built_in_manager.BuiltInManager(this);
  aiContextDatasourceManager = new import_ai_context_datasource_manager.AIContextDatasourceManager(this);
  aiCodingManager = new import_ai_coding_manager.AICodingManager(this);
  workContextHandler = (0, import_work_context_handler.createWorkContextHandler)(this);
  documentLoaders = new import_document_loader.DocumentLoaders(this);
  snowflake;
  /**
   * Check if the AI employee is a builder/admin-only type (e.g., Nathan, Orin).
   * These employees have powerful capabilities (coding, schema modification) and should be restricted to admins.
   */
  isBuilderAI(username) {
    const BUILDER_AI_USERNAMES = ["nathan", "orin", "dara"];
    return BUILDER_AI_USERNAMES.includes(username);
  }
  async afterAdd() {
  }
  async beforeLoad() {
    const pluginRecord = await this.db.getRepository("applicationPlugins").findOne({
      filter: {
        name: this.name
      }
    });
    this.snowflake = new import_snowflake.default(pluginRecord == null ? void 0 : pluginRecord.createdAt.getTime());
    this.app.cronJobManager.addJob({
      cronTime: "0 0 2 * * *",
      onTick: async () => {
        try {
          const checkpointSaver = new import_checkpoints.SequelizeCollectionSaver(() => this.app.mainDataSource);
          const checkpointCleaner = new import_checkpoints.CheckpointCleaner(() => this.app.mainDataSource, checkpointSaver);
          const expiredAt = new Date(Date.now() - 48 * 60 * 60 * 1e3);
          await checkpointCleaner.cleanOutdated(expiredAt);
        } catch (e) {
          this.app.log.error("langChain checkpoint clean job fail", e);
        }
      }
    });
  }
  async load() {
    await (0, import_tools.loadDocsIndexes)();
    this.registerLLMProviders();
    this.registerTools();
    this.defineResources();
    this.setPermissions();
    this.registerWorkflow();
    this.registerWorkContextResolveStrategy();
  }
  async setupBuiltIn() {
    await this.builtInManager.createOrUpdateAIEmployee();
  }
  registerLLMProviders() {
    this.aiManager.registerLLMProvider("google-genai", import_google_genai.googleGenAIProviderOptions);
    this.aiManager.registerLLMProvider("openai", import_openai.openaiResponsesProviderOptions);
    this.aiManager.registerLLMProvider("anthropic", import_anthropic.anthropicProviderOptions);
    this.aiManager.registerLLMProvider("deepseek", import_deepseek.deepseekProviderOptions);
    this.aiManager.registerLLMProvider("dashscope", import_dashscope.dashscopeProviderOptions);
    this.aiManager.registerLLMProvider("ollama", import_ollama.ollamaProviderOptions);
    this.aiManager.registerLLMProvider("openai-completions", import_openai2.openaiCompletionsProviderOptions);
    this.aiManager.registerLLMProvider("kimi", import_kimi.kimiProviderOptions);
  }
  registerTools() {
    const toolsManager = this.ai.toolsManager;
    toolsManager.registerTools([(0, import_tools.createDocsSearchTool)(), (0, import_tools.createReadDocEntryTool)()]);
    toolsManager.registerDynamicTools((0, import_tools.getWorkflowCallers)(this, "workflowCaller"));
  }
  defineResources() {
    this.app.resourceManager.define(import_ai.default);
    this.app.resourceManager.define(import_aiConversations.default);
    this.app.resourceManager.define(import_aiTools.default);
    this.app.resourceManager.define(import_aiSettings.default);
    this.app.resourceManager.define(import_aiContextDatasources.aiContextDatasources);
    this.app.resourceManager.use(
      async (ctx, next) => {
        var _a;
        const { resourceName, actionName } = ctx.action;
        if (resourceName === "aiFiles" && actionName === "create") {
          const settings = await this.db.getRepository("aiSettings").findOne();
          const collection = ctx.db.getCollection("aiFiles");
          collection.options.storage = (_a = settings == null ? void 0 : settings.options) == null ? void 0 : _a.storage;
        }
        await next();
      },
      { before: "createMiddleware" }
    );
    Object.entries(aiEmployeeActions).forEach(([name, action]) => {
      this.app.resourceManager.registerActionHandler(`aiEmployees:${name}`, action);
    });
  }
  setPermissions() {
    this.app.acl.registerSnippet({
      name: `pm.${this.name}.llm-services`,
      actions: ["ai:*", "llmServices:*"]
    });
    this.app.acl.registerSnippet({
      name: `pm.${this.name}.ai-employees`,
      actions: ["aiEmployees:*", "aiTools:*", "roles.aiEmployees:*", "aiContextDatasources:*"]
    });
    this.app.acl.registerSnippet({
      name: `pm.${this.name}.ai-settings`,
      actions: ["aiSettings:*"]
    });
    this.app.acl.allow("aiConversations", "*", "loggedIn");
    this.app.acl.allow("aiContextDatasources", "get", "loggedIn");
    this.app.acl.allow("aiContextDatasources", "list", "loggedIn");
    this.app.acl.allow("aiContextDatasources", "preview", "loggedIn");
    this.app.acl.allow("aiFiles", "create", "loggedIn");
    this.app.acl.allow("aiSettings", "publicGet", "loggedIn");
    this.app.acl.allow("ai", "listAllEnabledModels", "loggedIn");
    this.app.acl.allow("aiEmployees", "listByUser", "loggedIn");
    this.app.acl.allow("aiEmployees", "updateUserPrompt", "loggedIn");
    this.app.acl.allow("aiTools", "list", "loggedIn");
    const workflowSnippet = this.app.acl.snippetManager.snippets.get("pm.workflow.workflows");
    if (workflowSnippet) {
      workflowSnippet.actions.push("ai:listModels");
    }
    this.app.db.on("roles.beforeCreate", async (instance) => {
      instance.set("allowNewAiEmployee", true);
    });
    this.app.db.on("roles.afterCreate", async (instance, { transaction }) => {
      const allAiEmployees = await this.app.db.getRepository("aiEmployees").find({
        transaction
      });
      const generalAiEmployees = allAiEmployees.filter((ai) => !this.isBuilderAI(ai.username));
      if (generalAiEmployees.length > 0) {
        await instance.addAiEmployees(generalAiEmployees, { transaction });
      }
    });
    this.app.db.on("aiEmployees.afterCreate", async (instance, { transaction }) => {
      const roles = await this.app.db.getRepository("roles").find({
        filter: {
          allowNewAiEmployee: true
        },
        transaction
      });
      let targetRoles = roles;
      if (this.isBuilderAI(instance.username)) {
        targetRoles = roles.filter((role) => role.name === "admin");
      }
      await this.app.db.getRepository("aiEmployees.roles", instance.username).add({
        tk: targetRoles.map((role) => role.name),
        transaction
      });
    });
  }
  registerWorkflow() {
    const workflow = this.app.pm.get("workflow");
    workflow.registerTrigger("ai-employee", import_ai_employee.AIEmployeeTrigger);
    workflow.registerInstruction("llm", import_llm.LLMInstruction);
  }
  registerWorkContextResolveStrategy() {
    this.workContextHandler.registerStrategy("datasource", {
      resolve: this.aiContextDatasourceManager.provideWorkContextResolveStrategy()
    });
    this.workContextHandler.registerStrategy("code-editor", {
      resolve: this.aiCodingManager.provideWorkContextResolveStrategy(),
      background: this.aiCodingManager.provideWorkContextBackgroundStrategy()
    });
  }
  handleSyncMessage(message) {
    const { type, payload } = message;
    switch (type) {
      case "aiEmployees:abortConversation":
        return (async () => {
          this.aiEmployeesManager.onAbortConversation(payload.sessionId);
        })();
    }
  }
  async install() {
    const aiSettings2 = await this.db.getRepository("aiSettings").findOne();
    if (aiSettings2) {
      return;
    }
    await this.db.getRepository("aiSettings").create({});
    await this.setupBuiltIn();
  }
  async upgrade() {
    await this.setupBuiltIn();
  }
  async afterEnable() {
  }
  async afterDisable() {
  }
  async remove() {
  }
  get repositories() {
    return {
      aiContextDatasources: this.repository("aiContextDatasources")
    };
  }
  get fileManager() {
    return this.app.pm.get("file-manager");
  }
  repository(collectionName) {
    return this.app.db.getRepository(collectionName);
  }
}
var plugin_default = PluginAIServer;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  PluginAIServer
});
