export namespace SpecV2 {
  export type TavernCardV2 = {
    spec: "chara_card_v2";
    spec_version: "2.0"; // May 8th addition
    data: {
      name: string;
      description: string;
      personality: string;
      scenario: string;
      first_mes: string;
      mes_example: string;

      // New fields start here
      creator_notes: string;
      system_prompt: string;
      post_history_instructions: string;
      alternate_greetings: Array<string>;
      character_book?: CharacterBook;

      // May 8th additions
      tags: Array<string>;
      creator: string;
      character_version: string;
      extensions: Record<string, any>;
    };
  };

  /**
   * ? as in `name?: string` means the `name` property may be absent from the JSON
   * (aka this property is optional)
   * OPTIONAL PROPERTIES ARE ALLOWED TO BE UNSUPPORTED BY EDITORS AND DISREGARDED BY
   * FRONTENDS, however they must never be destroyed if already in the data.
   *
   * the `extensions` properties may contain arbitrary key-value pairs, but you are encouraged
   * to namespace the keys to prevent conflicts, and you must never destroy
   * unknown key-value pairs from the data. `extensions` is mandatory and must
   * default to `{}`. `extensions` exists for the character book itself, and for
   * each entry.
   **/
  export type CharacterBook = {
    name?: string;
    description?: string;
    scan_depth?: number; // agnai: "Memory: Chat History Depth"
    token_budget?: number; // agnai: "Memory: Context Limit"
    recursive_scanning?: boolean; // no agnai equivalent. whether entry content can trigger other entries
    extensions: Record<string, any>;
    entries: Array<{
      keys: Array<string>;
      content: string;
      extensions: Record<string, any>;
      enabled: boolean;
      insertion_order: number; // if two entries inserted, lower "insertion order" = inserted higher
      case_sensitive?: boolean;

      // FIELDS WITH NO CURRENT EQUIVALENT IN SILLY
      name?: string; // not used in prompt engineering
      priority?: number; // if token budget reached, lower priority value = discarded first

      // FIELDS WITH NO CURRENT EQUIVALENT IN AGNAI
      id?: number; // not used in prompt engineering
      comment?: string; // not used in prompt engineering
      selective?: boolean; // if `true`, require a key from both `keys` and `secondary_keys` to trigger the entry
      secondary_keys?: Array<string>; // see field `selective`. ignored if selective == false
      constant?: boolean; // if true, always inserted in the prompt (within budget limit)
      position?: "before_char" | "after_char"; // whether the entry is placed before or after the character defs
    }>;
  };
}
