怎么对sdapi/v1/embeddings发起请求,获取pt模型列表

灵感来自42的sd-switch,因为embeddings也跟sd-models是有官方api的,所以我想试试能不能获取embeddings文件夹中的embeddings模型列表

http://127.0.0.1:7860/sdapi/v1/embeddings

127.0.0.1如果有公网ip可以换成公网地址

api文档·截图-需要本地打开sd



以我的embedings文件夹作为例子:

Curl是

curl -X 'GET' \
  'http://127.0.0.1:7860/sdapi/v1/embeddings' \
  -H 'accept: application/json'

Request URL是

http://127.0.0.1:7860/sdapi/v1/embeddings

Response body是

{
  "loaded": {
    "EasyNegative": {
      "step": null,
      "sd_checkpoint": null,
      "sd_checkpoint_name": null,
      "shape": 768,
      "vectors": 8
    },
    "kbxll": {
      "step": 10000,
      "sd_checkpoint": "e6e8e1fc",
      "sd_checkpoint_name": "latest",
      "shape": 768,
      "vectors": 15
    },
    "伊蕾娜": {
      "step": null,
      "sd_checkpoint": null,
      "sd_checkpoint_name": null,
      "shape": 768,
      "vectors": 8
    },
    "旗袍萝莉": {
      "step": 10000,
      "sd_checkpoint": "1a2d6e1ec9",
      "sd_checkpoint_name": "aaa-nai-training",
      "shape": 768,
      "vectors": 20
    },
    "波奇": {
      "step": 16000,
      "sd_checkpoint": "a7529df023",
      "sd_checkpoint_name": "nai",
      "shape": 768,
      "vectors": 18
    },
    "泥岩": {
      "step": 9201,
      "sd_checkpoint": "e6e8e1fc",
      "sd_checkpoint_name": "7G_animefull-latest",
      "shape": 768,
      "vectors": 11
    },
    "玛奇玛": {
      "step": 8000,
      "sd_checkpoint": "89d59c3dde",
      "sd_checkpoint_name": "novel-ai",
      "shape": 768,
      "vectors": 16
    }
  },
  "skipped": {}
}

Response body是

{
  "loaded": {
    "EasyNegative": {
      "step": null,
      "sd_checkpoint": null,
      "sd_checkpoint_name": null,
      "shape": 768,
      "vectors": 8
    },
    "kbxll": {
      "step": 10000,
      "sd_checkpoint": "e6e8e1fc",
      "sd_checkpoint_name": "latest",
      "shape": 768,
      "vectors": 15
    },
    "伊蕾娜": {
      "step": null,
      "sd_checkpoint": null,
      "sd_checkpoint_name": null,
      "shape": 768,
      "vectors": 8
    },
    "旗袍萝莉": {
      "step": 10000,
      "sd_checkpoint": "1a2d6e1ec9",
      "sd_checkpoint_name": "aaa-nai-training",
      "shape": 768,
      "vectors": 20
    },
    "波奇": {
      "step": 16000,
      "sd_checkpoint": "a7529df023",
      "sd_checkpoint_name": "nai",
      "shape": 768,
      "vectors": 18
    },
    "泥岩": {
      "step": 9201,
      "sd_checkpoint": "e6e8e1fc",
      "sd_checkpoint_name": "7G_animefull-latest",
      "shape": 768,
      "vectors": 11
    },
    "玛奇玛": {
      "step": 8000,
      "sd_checkpoint": "89d59c3dde",
      "sd_checkpoint_name": "novel-ai",
      "shape": 768,
      "vectors": 16
    }
  },
  "skipped": {}
}
Response headers是
 content-length: 786 
 content-type: application/json 
 date: Wed,03 May 2023 12:32:46 GMT 
 server: uvicorn 
 x-process-time: 0.0031 

我尝试写的代码如下:

import { Context, Logger, Schema, trimSlash } from "koishi";

export const name = "sd-switch";

export const usage = "查看模型、pt、lora列表";
export interface Config {
  endpoint?: string;
}

export const Config: Schema<Config> = Schema.object({
  endpoint: Schema.string()
    .description("SD-WebUI 服务器地址。")
    .default("http://127.0.0.1:7860"),
});

const logger = new Logger(name);

const MODELS_ENDPOINT = "/sdapi/v1/sd-models";
const PT_ENDPOINT = "/sdapi/v1/embeddings";

export function apply(ctx: Context, config: Config) {
  const cmd1 = ctx
    .command("查看模型", "ai绘画的模型列表")
    .alias("获取模型列表")
    .action(async ({ session }) => {
      const models = [];
      let vae = "";
      let model = "";

      async function getModelList() {
        try {
          const res = await ctx.http.axios(
            trimSlash(config.endpoint) + MODELS_ENDPOINT
          );
          res.data.forEach((item) => models.push(item.title));
        } catch (err) {
          session.send(session.text("获取模型列表失败"));
          throw err;
        }
      }

      // 定义函数 sendModels,该函数向用户发送可用的模型列表
      async function sendModels() {
        // 向 API 发送请求获取模型列表
        await getModelList();
        // 向 API 发送请求获取当前使用的模型
        await getInfo();
        session.send(
          `当前模型为:${model}\n` +
            "当前可用模型有:\n" +
            models.map((model, i) => `${i + 1}.${model}\n`).join("")
        );
      }
      async function getInfo() {
        session.send(session.text(".inQuery"));
        try {
          const res = await ctx.http.axios(
            trimSlash(config.endpoint) + MODELS_ENDPOINT
          );
          vae = res.data.sd_vae;
          model = res.data.sd_model_checkpoint;
        } catch (err) {
          session.send(session.text(".queryErr"));
          throw err;
        }
      }
      await sendModels();
    });

  const cmd2 = ctx
    .command("查看pt", "ai绘画的pt列表")
    .action(async ({ session }) => {
      const pt = [];

      async function getPtList() {
        try {
          const res = await ctx.http.axios(
            trimSlash(config.endpoint) + PT_ENDPOINT
          );
          if (Array.isArray(res.data)) {
            res.data.forEach((item) => pt.push(item.title));
          } else {
            throw new Error("获取的数据格式不正确");
          }
        } catch (err) {
          session.send(session.text("获取pt列表失败"));
          throw err;
        }
      }
      async function sendPt() {
        await getPtList();
        session.send(`
        当前可用pt有:
        ${pt.map((pt, i) => `${i + 1}.${pt}`).join("\n")}
      `);
      }

      await sendPt();
    });
}



预期的结果,当我是获取输入"查看pt"时,插件会给我返回到pt列表

实际的效果是:获取pt列表失败

日志如图:

2 个赞

谢谢
@MirrorCY

指导和修改,现在修改后的代码如下:

import { Context, Logger, Schema, trimSlash } from "koishi";

export const name = "sd-list";

export const usage = "查看模型、pt、lora列表";
export interface Config {
  endpoint?: string;
}

export const Config: Schema<Config> = Schema.object({
  endpoint: Schema.string()
    .description("SD-WebUI 服务器地址。")
    .default("http://127.0.0.1:7860"),
});

const logger = new Logger(name);

const MODELS_ENDPOINT = "/sdapi/v1/sd-models";
const PT_ENDPOINT = "/sdapi/v1/embeddings";

export function apply(ctx: Context, config: Config) {
  const cmd1 = ctx
    .command("查看model", "ai绘画的model列表")
    .action(async ({ session }) => {
      let modelTitles = [];

      async function getModelList() {
        try {
          const res = await ctx.http.get(
            trimSlash(config.endpoint) + MODELS_ENDPOINT
          );
          modelTitles = res.map((model) => model.title);
        } catch (err) {
          session.send(session.text("获取model列表失败"));
          throw err;
        }
      }

      async function sendModels() {
        await getModelList();
        session.send(
          `当前可用model有:\n${modelTitles
            .map((title, i) => `${i + 1}.${title}`)
            .join("\n")}`
        );
      }

      await sendModels();
    });

  const cmd2 = ctx
    .command("查看pt", "ai绘画的pt列表")
    .action(async ({ session }) => {
      let pt = [];

      async function getPtList() {
        try {
          const res = await ctx.http.get(
            trimSlash(config.endpoint) + PT_ENDPOINT
          );
          pt = Object.keys(res.loaded);
        } catch (err) {
          session.send(session.text("获取pt列表失败"));
          throw err;
        }
      }
      async function sendPt() {
        await getPtList();
        session.send(
          `当前可用pt有:\n${pt.map((pt, i) => `${i + 1}.${pt}`).join("\n")}`
        );
      }

      await sendPt();
    });
}

2 个赞

at 都能 at 歪来

2 个赞

@MirrorCY

2 个赞

我手动打的,以为已经艾特成功了

2 个赞

发送前可以看到预览,确保不会发出蠢蠢帖子~

2 个赞