import { Cognitive } from "@botpress/cognitive";
import { getWasmTokenizer } from "@bpinternal/thicktoken";
import { z } from "@bpinternal/zui";
import { TableAdapter } from "./adapters/botpress-table";
import { MemoryAdapter } from "./adapters/memory";
const _ActiveLearning = z.object({
  enable: z.boolean().describe("Whether to enable active learning").default(false),
  tableName: z.string().regex(
    /^[A-Za-z0-9_/-]{1,100}Table$/,
    "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes"
  ).describe("The name of the table to store active learning tasks").default("ActiveLearningTable"),
  taskId: z.string().regex(
    /^[A-Za-z0-9_/-]{1,100}$/,
    "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes"
  ).describe("The ID of the task").default("default")
});
const _ZaiConfig = z.object({
  client: z.custom(),
  userId: z.string().describe("The ID of the user consuming the API").optional(),
  modelId: z.custom(
    (value) => {
      if (typeof value !== "string") {
        return false;
      }
      if (value !== "best" && value !== "fast" && !value.includes(":")) {
        return false;
      }
      return true;
    },
    {
      message: "Invalid model ID"
    }
  ).describe("The ID of the model you want to use").default("best"),
  activeLearning: _ActiveLearning.default({ enable: false }),
  namespace: z.string().regex(
    /^[A-Za-z0-9_/-]{1,100}$/,
    "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes"
  ).default("zai")
});
export class Zai {
  static tokenizer = null;
  client;
  _originalConfig;
  _userId;
  Model;
  ModelDetails;
  namespace;
  adapter;
  activeLearning;
  constructor(config) {
    this._originalConfig = config;
    const parsed = _ZaiConfig.parse(config);
    this.client = Cognitive.isCognitiveClient(parsed.client) ? parsed.client : new Cognitive({ client: parsed.client });
    this.namespace = parsed.namespace;
    this._userId = parsed.userId;
    this.Model = parsed.modelId;
    this.activeLearning = parsed.activeLearning;
    this.adapter = parsed.activeLearning?.enable ? new TableAdapter({
      client: this.client.client,
      tableName: parsed.activeLearning.tableName
    }) : new MemoryAdapter([]);
  }
  /** @internal */
  async callModel(props) {
    return this.client.generateContent({
      reasoningEffort: "none",
      ...props,
      model: this.Model,
      userId: this._userId
    });
  }
  async getTokenizer() {
    Zai.tokenizer ??= await (async () => {
      while (!getWasmTokenizer) {
        await new Promise((resolve) => setTimeout(resolve, 25));
      }
      return getWasmTokenizer();
    })();
    return Zai.tokenizer;
  }
  async fetchModelDetails() {
    if (!this.ModelDetails) {
      this.ModelDetails = await this.client.getModelDetails(this.Model);
    }
  }
  get taskId() {
    if (!this.activeLearning.enable) {
      return void 0;
    }
    return `${this.namespace}/${this.activeLearning.taskId}`.replace(/\/+/g, "/");
  }
  with(options) {
    return new Zai({
      ...this._originalConfig,
      ...options
    });
  }
  learn(taskId) {
    return new Zai({
      ...this._originalConfig,
      activeLearning: { ...this.activeLearning, taskId, enable: true }
    });
  }
}
