"use strict";
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);

// src/playground/server.ts
var server_exports = {};
__export(server_exports, {
  default: () => PlaygroundServer
});
module.exports = __toCommonJS(server_exports);
var import_node_crypto = require("crypto");
var import_node_fs = require("fs");
var import_node_path = require("path");

// src/common/utils.ts
var import_ai_model = require("@midscene_spp/core/ai-model");
var import_utils = require("@midscene_spp/core/utils");
var import_env = require("@midscene_spp/shared/env");
var import_extractor = require("@midscene_spp/shared/extractor");
var import_img = require("@midscene_spp/shared/img");
var import_utils2 = require("@midscene_spp/shared/utils");
var import_dayjs = __toESM(require("dayjs"));
var ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED = "NOT_IMPLEMENTED_AS_DESIGNED";

// src/playground/server.ts
var import_utils4 = require("@midscene_spp/core/utils");
var import_constants = require("@midscene_spp/shared/constants");
var import_env2 = require("@midscene_spp/shared/env");
var import_utils5 = require("@midscene_spp/shared/utils");
var import_cors = __toESM(require("cors"));
var import_dotenv = __toESM(require("dotenv"));
var import_express = __toESM(require("express"));
var defaultPort = import_constants.PLAYGROUND_SERVER_PORT;
var errorHandler = (err, req, res, next) => {
  console.error(err);
  res.status(500).json({
    error: err.message
  });
};
var setup = async () => {
  if (!import_utils5.ifInBrowser) {
    const { parsed } = import_dotenv.default.config();
    if (parsed) {
      (0, import_env2.overrideAIConfig)(parsed);
    }
  }
};
var PlaygroundServer = class {
  constructor(pageClass, agentClass, staticPath) {
    this.app = (0, import_express.default)();
    this.tmpDir = (0, import_utils4.getTmpDir)();
    this.pageClass = pageClass;
    this.agentClass = agentClass;
    this.staticPath = staticPath;
    this.taskProgressTips = {};
    setup();
  }
  filePathForUuid(uuid2) {
    return (0, import_node_path.join)(this.tmpDir, `${uuid2}.json`);
  }
  saveContextFile(uuid2, context) {
    const tmpFile = this.filePathForUuid(uuid2);
    console.log(`save context file: ${tmpFile}`);
    (0, import_node_fs.writeFileSync)(tmpFile, context);
    return tmpFile;
  }
  async launch(port) {
    this.port = port || defaultPort;
    this.app.use(errorHandler);
    this.app.use(
      (0, import_cors.default)({
        origin: "*",
        credentials: true
      })
    );
    this.app.get("/status", (0, import_cors.default)(), async (req, res) => {
      res.send({
        status: "ok"
      });
    });
    this.app.get("/context/:uuid", async (req, res) => {
      const { uuid: uuid2 } = req.params;
      const contextFile = this.filePathForUuid(uuid2);
      if (!(0, import_node_fs.existsSync)(contextFile)) {
        return res.status(404).json({
          error: "Context not found"
        });
      }
      const context = (0, import_node_fs.readFileSync)(contextFile, "utf8");
      res.json({
        context
      });
    });
    this.app.get("/task-progress/:requestId", (0, import_cors.default)(), async (req, res) => {
      const { requestId } = req.params;
      res.json({
        tip: this.taskProgressTips[requestId] || ""
      });
    });
    this.app.post(
      "/playground-with-context",
      import_express.default.json({ limit: "50mb" }),
      async (req, res) => {
        const context = req.body.context;
        if (!context) {
          return res.status(400).json({
            error: "context is required"
          });
        }
        const uuid2 = (0, import_node_crypto.randomUUID)();
        this.saveContextFile(uuid2, context);
        return res.json({
          location: `/playground/${uuid2}`,
          uuid: uuid2
        });
      }
    );
    this.app.post(
      "/execute",
      import_express.default.json({ limit: "30mb" }),
      async (req, res) => {
        const { context, type, prompt, requestId, deepThink } = req.body;
        if (!context) {
          return res.status(400).json({
            error: "context is required"
          });
        }
        if (!type) {
          return res.status(400).json({
            error: "type is required"
          });
        }
        if (!prompt) {
          return res.status(400).json({
            error: "prompt is required"
          });
        }
        const page = new this.pageClass(context);
        const agent = new this.agentClass(page);
        if (requestId) {
          this.taskProgressTips[requestId] = "";
          agent.onTaskStartTip = (tip) => {
            this.taskProgressTips[requestId] = tip;
          };
        }
        const response = {
          result: null,
          dump: null,
          error: null,
          reportHTML: null,
          requestId
        };
        const startTime = Date.now();
        try {
          if (type === "aiQuery") {
            response.result = await agent.aiQuery(prompt);
          } else if (type === "aiAction") {
            response.result = await agent.aiAction(prompt);
          } else if (type === "aiAssert") {
            response.result = await agent.aiAssert(prompt, void 0, {
              keepRawResponse: true
            });
          } else if (type === "aiTap") {
            response.result = await agent.aiTap(prompt, {
              deepThink
            });
          } else {
            response.error = `Unknown type: ${type}`;
          }
        } catch (error) {
          if (!error.message.includes(ERROR_CODE_NOT_IMPLEMENTED_AS_DESIGNED)) {
            response.error = error.message;
          }
        }
        try {
          response.dump = JSON.parse(agent.dumpDataString());
          response.reportHTML = agent.reportHTMLString() || null;
          agent.writeOutActionDumps();
        } catch (error) {
          console.error(
            `write out dump failed: requestId: ${requestId}, ${error.message}`
          );
        }
        res.send(response);
        const timeCost = Date.now() - startTime;
        if (response.error) {
          console.error(
            `handle request failed after ${timeCost}ms: requestId: ${requestId}, ${response.error}`
          );
        } else {
          console.log(
            `handle request done after ${timeCost}ms: requestId: ${requestId}`
          );
        }
      }
    );
    this.app.post(
      "/config",
      import_express.default.json({ limit: "1mb" }),
      async (req, res) => {
        const { aiConfig } = req.body;
        if (!aiConfig || typeof aiConfig !== "object") {
          return res.status(400).json({
            error: "aiConfig is required and must be an object"
          });
        }
        try {
          (0, import_env2.overrideAIConfig)(aiConfig);
          return res.json({
            status: "ok",
            message: "AI config updated successfully"
          });
        } catch (error) {
          console.error(`Failed to update AI config: ${error.message}`);
          return res.status(500).json({
            error: `Failed to update AI config: ${error.message}`
          });
        }
      }
    );
    if (this.staticPath) {
      this.app.get("/", (req, res) => {
        res.redirect("/index.html");
      });
      this.app.get("*", (req, res) => {
        const requestedPath = (0, import_node_path.join)(this.staticPath, req.path);
        if ((0, import_node_fs.existsSync)(requestedPath)) {
          res.sendFile(requestedPath);
        } else {
          res.sendFile((0, import_node_path.join)(this.staticPath, "index.html"));
        }
      });
    }
    return new Promise((resolve, reject) => {
      const port2 = this.port;
      this.server = this.app.listen(port2, () => {
        resolve(this);
      });
    });
  }
  close() {
    if (this.server) {
      return this.server.close();
    }
  }
};

//# sourceMappingURL=midscene-server.js.map