koishi-plugin-hhs-huatu 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +51 -17
- package/lib/queueSystem.d.ts +4 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -471,9 +471,6 @@ async function login(ctx, email, password) {
|
|
|
471
471
|
let startIndex = ctx.runtime.currentTokenIndex;
|
|
472
472
|
let strategy = ctx.config.tokenStrategy || "round-robin";
|
|
473
473
|
logger.debug(`使用token策略: ${strategy}`);
|
|
474
|
-
if (strategy === "parallel" && !ctx.runtime.tokenUsage) {
|
|
475
|
-
ctx.runtime.tokenUsage = {};
|
|
476
|
-
}
|
|
477
474
|
if (strategy === "random") {
|
|
478
475
|
startIndex = Math.floor(Math.random() * ctx.config.token.length);
|
|
479
476
|
ctx.runtime.currentTokenIndex = startIndex;
|
|
@@ -481,9 +478,9 @@ async function login(ctx, email, password) {
|
|
|
481
478
|
let foundUnusedToken = false;
|
|
482
479
|
for (let i = 0; i < ctx.config.token.length; i++) {
|
|
483
480
|
const checkIndex = (ctx.runtime.currentTokenIndex + i) % ctx.config.token.length;
|
|
484
|
-
|
|
481
|
+
const tokenUsage = ctx.runtime.tokenUsage || {};
|
|
482
|
+
if (!tokenUsage[checkIndex]) {
|
|
485
483
|
startIndex = checkIndex;
|
|
486
|
-
ctx.runtime.tokenUsage[checkIndex] = true;
|
|
487
484
|
ctx.runtime.currentTokenIndex = (checkIndex + 1) % ctx.config.token.length;
|
|
488
485
|
foundUnusedToken = true;
|
|
489
486
|
logger.debug(`并行策略选择token索引 ${checkIndex},下一次从索引 ${ctx.runtime.currentTokenIndex} 开始检查`);
|
|
@@ -1523,12 +1520,19 @@ __name(auditImage, "auditImage");
|
|
|
1523
1520
|
|
|
1524
1521
|
// src/queueSystem.ts
|
|
1525
1522
|
var QueueSystem = class {
|
|
1526
|
-
constructor(ctx, config, generateImageFn, membershipSystem) {
|
|
1523
|
+
constructor(ctx, config, generateImageFn, membershipSystem, initialTokenUsage) {
|
|
1527
1524
|
this.ctx = ctx;
|
|
1528
1525
|
this.config = config;
|
|
1529
1526
|
this.generateImageFn = generateImageFn;
|
|
1530
1527
|
this.membershipSystem = membershipSystem || null;
|
|
1531
1528
|
this.maxConcurrentTasks = config.tokenStrategy === "parallel" && Array.isArray(config.token) ? Math.min(config.maxConcurrentRequests || 1, config.token.length) : config.maxConcurrentRequests || 1;
|
|
1529
|
+
if (initialTokenUsage) {
|
|
1530
|
+
this.tokenUsage = { ...initialTokenUsage };
|
|
1531
|
+
} else if (config.tokenStrategy === "parallel" && Array.isArray(config.token)) {
|
|
1532
|
+
for (let i = 0; i < config.token.length; i++) {
|
|
1533
|
+
this.tokenUsage[i] = false;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1532
1536
|
}
|
|
1533
1537
|
static {
|
|
1534
1538
|
__name(this, "QueueSystem");
|
|
@@ -1552,6 +1556,9 @@ var QueueSystem = class {
|
|
|
1552
1556
|
maxConcurrentTasks;
|
|
1553
1557
|
// 会员系统引用
|
|
1554
1558
|
membershipSystem = null;
|
|
1559
|
+
// Token管理相关
|
|
1560
|
+
tokenLock = Promise.resolve();
|
|
1561
|
+
tokenUsage = /* @__PURE__ */ Object.create(null);
|
|
1555
1562
|
// 获取锁
|
|
1556
1563
|
async acquireRedrawLock() {
|
|
1557
1564
|
if (!this.redrawLock) {
|
|
@@ -1589,6 +1596,20 @@ var QueueSystem = class {
|
|
|
1589
1596
|
this.usedTokenIndices.add(newIndex);
|
|
1590
1597
|
return newIndex;
|
|
1591
1598
|
}
|
|
1599
|
+
// 获取token锁,确保token选择的原子性
|
|
1600
|
+
async acquireTokenLock() {
|
|
1601
|
+
const release = this.tokenLock;
|
|
1602
|
+
let releaseFn = null;
|
|
1603
|
+
this.tokenLock = new Promise((resolve3) => {
|
|
1604
|
+
releaseFn = resolve3;
|
|
1605
|
+
});
|
|
1606
|
+
await release;
|
|
1607
|
+
return () => {
|
|
1608
|
+
if (releaseFn) {
|
|
1609
|
+
releaseFn();
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1592
1613
|
// 处理队列
|
|
1593
1614
|
async processQueue() {
|
|
1594
1615
|
if (this.taskQueue.length === 0) return;
|
|
@@ -1596,10 +1617,8 @@ var QueueSystem = class {
|
|
|
1596
1617
|
const tasksToProcess = Math.min(this.maxConcurrentTasks - this.processingTasks, this.taskQueue.length);
|
|
1597
1618
|
if (this.config.tokenStrategy === "parallel" && Array.isArray(this.ctx.config.token)) {
|
|
1598
1619
|
this.ctx.logger.debug(`处理队列中的任务,当前处理中: ${this.processingTasks},即将处理: ${tasksToProcess},队列剩余: ${this.taskQueue.length},最大并发: ${this.maxConcurrentTasks}`);
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
this.ctx.logger.debug(`当前token使用情况: 已用 ${usedTokens.length}/${this.ctx.config.token.length} (索引: ${usedTokens.join(", ")})`);
|
|
1602
|
-
}
|
|
1620
|
+
const usedTokens = Object.entries(this.tokenUsage).filter(([_, used]) => used).map(([index]) => index);
|
|
1621
|
+
this.ctx.logger.debug(`当前token使用情况: 已用 ${usedTokens.length}/${this.ctx.config.token.length} (索引: ${usedTokens.join(", ")})`);
|
|
1603
1622
|
}
|
|
1604
1623
|
for (let i = 0; i < tasksToProcess; i++) {
|
|
1605
1624
|
this.processingTasks++;
|
|
@@ -1625,6 +1644,7 @@ var QueueSystem = class {
|
|
|
1625
1644
|
}
|
|
1626
1645
|
}
|
|
1627
1646
|
Promise.resolve().then(async () => {
|
|
1647
|
+
const releaseTokenLock = await this.acquireTokenLock();
|
|
1628
1648
|
try {
|
|
1629
1649
|
const result = await this.generateImageFn(task.session, task.options, task.input);
|
|
1630
1650
|
task.resolve(result);
|
|
@@ -1632,9 +1652,10 @@ var QueueSystem = class {
|
|
|
1632
1652
|
task.reject(err);
|
|
1633
1653
|
} finally {
|
|
1634
1654
|
this.processingTasks--;
|
|
1655
|
+
releaseTokenLock();
|
|
1635
1656
|
if (Array.isArray(this.ctx.config.token)) {
|
|
1636
|
-
if (this.config.tokenStrategy === "parallel"
|
|
1637
|
-
const usedTokens = Object.entries(this.
|
|
1657
|
+
if (this.config.tokenStrategy === "parallel") {
|
|
1658
|
+
const usedTokens = Object.entries(this.tokenUsage).filter(([_, used]) => used).map(([index]) => index);
|
|
1638
1659
|
this.ctx.logger.debug(`任务完成后token使用情况(parallel): 已用 ${usedTokens.length}/${this.ctx.config.token.length} (索引: ${usedTokens.join(", ")})`);
|
|
1639
1660
|
} else if (this.config.tokenStrategy === "round-robin") {
|
|
1640
1661
|
this.ctx.logger.debug(`任务完成后token索引(round-robin): ${this.ctx.runtime?.currentTokenIndex}/${this.ctx.config.token.length - 1}`);
|
|
@@ -2168,6 +2189,16 @@ function apply(ctx, config) {
|
|
|
2168
2189
|
const tasks = /* @__PURE__ */ Object.create(null);
|
|
2169
2190
|
const globalTasks = /* @__PURE__ */ new Set();
|
|
2170
2191
|
let queueSystem;
|
|
2192
|
+
const syncTokenUsage = /* @__PURE__ */ __name(() => {
|
|
2193
|
+
if (ctx.runtime && Array.isArray(ctx.config.token)) {
|
|
2194
|
+
if (!ctx.runtime.tokenUsage) {
|
|
2195
|
+
ctx.runtime.tokenUsage = {};
|
|
2196
|
+
for (let i = 0; i < ctx.config.token.length; i++) {
|
|
2197
|
+
ctx.runtime.tokenUsage[i] = false;
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
}, "syncTokenUsage");
|
|
2171
2202
|
let tokenTask = null;
|
|
2172
2203
|
const getToken = /* @__PURE__ */ __name(async (session) => {
|
|
2173
2204
|
try {
|
|
@@ -2284,6 +2315,7 @@ function apply(ctx, config) {
|
|
|
2284
2315
|
}
|
|
2285
2316
|
return { width, height, custom: true };
|
|
2286
2317
|
}, "resolution");
|
|
2318
|
+
syncTokenUsage();
|
|
2287
2319
|
async function generateImage(session, options2, input) {
|
|
2288
2320
|
ctx.logger.debug(`generateImage开始处理,sessionId=${session.id},userId=${session.userId}`);
|
|
2289
2321
|
const sessionObj = session;
|
|
@@ -2940,7 +2972,7 @@ function apply(ctx, config) {
|
|
|
2940
2972
|
}
|
|
2941
2973
|
}
|
|
2942
2974
|
__name(generateImage, "generateImage");
|
|
2943
|
-
queueSystem = new QueueSystem(ctx, config, generateImage, membershipSystem);
|
|
2975
|
+
queueSystem = new QueueSystem(ctx, config, generateImage, membershipSystem, ctx.runtime?.tokenUsage);
|
|
2944
2976
|
const cmd = ctx.command("novelai [prompts...]").alias("nai").alias("imagine").alias("nai4", { options: { model: "nai-v4-full", sampler: "k_euler_a", iterations: 1, batch: 1 } }).alias("nai4c", { options: { model: "nai-v4-curated-preview", sampler: "k_euler_a", iterations: 1, batch: 1 } }).alias("nai4-5c", { options: { model: "nai-v4-5-curated", sampler: "k_euler_a", iterations: 1, batch: 1 } }).alias("nai4-5", { options: { model: "nai-v4-5-full", sampler: "k_euler_a", iterations: 1, batch: 1 } }).userFields(["authority"]).shortcut("imagine", { i18n: true, fuzzy: true }).shortcut("enhance", { i18n: true, fuzzy: true, options: { enhance: true } }).option("enhance", "-e", { hidden: some(restricted, thirdParty, noImage) }).option("model", "-m <model>", { type: models, hidden: thirdParty }).option("resolution", "-r <resolution>", { type: resolution2 }).option("output", "-o", { type: ["minimal", "default", "verbose"] }).option("override", "-O", { hidden: restricted }).option("sampler", "-s <sampler>").option("seed", "-x <seed:number>").option("steps", "-t <step>", { type: step, hidden: restricted }).option("scale", "-c <scale:number>").option("rescale", "-R <rescale:number>").option("noise", "-n <noise:number>", { hidden: some(restricted, thirdParty) }).option("strength", "-N <strength:number>", { hidden: restricted }).option("hiresFix", "-H", { hidden: /* @__PURE__ */ __name(() => config.type !== "sd-webui", "hidden") }).option("hiresFixSteps", "<step>", { type: step, hidden: /* @__PURE__ */ __name(() => config.type !== "sd-webui", "hidden") }).option("smea", "-S", { hidden: /* @__PURE__ */ __name(() => config.model !== "nai-v3", "hidden") }).option("smeaDyn", "-d", { hidden: /* @__PURE__ */ __name(() => config.model !== "nai-v3", "hidden") }).option("scheduler", "-C <scheduler:string>", {
|
|
2945
2977
|
hidden: /* @__PURE__ */ __name(() => config.type === "naifu", "hidden"),
|
|
2946
2978
|
type: ["token", "login"].includes(config.type) ? scheduler.nai : config.type === "sd-webui" ? scheduler.sd : config.type === "stable-horde" ? scheduler.horde : []
|
|
@@ -3247,8 +3279,9 @@ function apply(ctx, config) {
|
|
|
3247
3279
|
queueSystem.userTasks[currentUserId]--;
|
|
3248
3280
|
targetBot.sendMessage(targetChannelId, value);
|
|
3249
3281
|
if (Array.isArray(ctx.config.token)) {
|
|
3250
|
-
if (config.tokenStrategy === "parallel"
|
|
3251
|
-
const
|
|
3282
|
+
if (config.tokenStrategy === "parallel") {
|
|
3283
|
+
const queueTokenUsage = queueSystem.tokenUsage || {};
|
|
3284
|
+
const usedTokens = Object.entries(queueTokenUsage).filter(([_, used]) => used).map(([index2]) => index2);
|
|
3252
3285
|
ctx.logger.debug(`重画任务 ${taskUniqueId} 完成,当前token使用情况: ${usedTokens.join(", ")}`);
|
|
3253
3286
|
} else if (config.tokenStrategy === "round-robin") {
|
|
3254
3287
|
ctx.logger.debug(`重画任务 ${taskUniqueId} 完成,当前token索引: ${ctx.runtime?.currentTokenIndex}`);
|
|
@@ -3266,8 +3299,9 @@ function apply(ctx, config) {
|
|
|
3266
3299
|
handleError(ctx, session, err)
|
|
3267
3300
|
);
|
|
3268
3301
|
if (Array.isArray(ctx.config.token)) {
|
|
3269
|
-
if (config.tokenStrategy === "parallel"
|
|
3270
|
-
const
|
|
3302
|
+
if (config.tokenStrategy === "parallel") {
|
|
3303
|
+
const queueTokenUsage = queueSystem.tokenUsage || {};
|
|
3304
|
+
const usedTokens = Object.entries(queueTokenUsage).filter(([_, used]) => used).map(([index2]) => index2);
|
|
3271
3305
|
ctx.logger.debug(`重画任务 ${taskUniqueId} 失败,当前token使用情况: ${usedTokens.join(", ")}`);
|
|
3272
3306
|
} else if (config.tokenStrategy === "round-robin") {
|
|
3273
3307
|
ctx.logger.debug(`重画任务 ${taskUniqueId} 失败,当前token索引: ${ctx.runtime?.currentTokenIndex}`);
|
package/lib/queueSystem.d.ts
CHANGED
|
@@ -28,10 +28,13 @@ export declare class QueueSystem {
|
|
|
28
28
|
private redrawWaitQueue;
|
|
29
29
|
maxConcurrentTasks: number;
|
|
30
30
|
private membershipSystem;
|
|
31
|
-
|
|
31
|
+
private tokenLock;
|
|
32
|
+
private tokenUsage;
|
|
33
|
+
constructor(ctx: Context, config: Config, generateImageFn: (session: Session<'authority'>, options: any, input: string) => Promise<any>, membershipSystem?: MembershipSystem, initialTokenUsage?: Dict<boolean>);
|
|
32
34
|
acquireRedrawLock(): Promise<void>;
|
|
33
35
|
releaseRedrawLock(): void;
|
|
34
36
|
getUniqueTokenIndex(currentIndex: number, tokenCount: number): number;
|
|
37
|
+
private acquireTokenLock;
|
|
35
38
|
processQueue(): Promise<void>;
|
|
36
39
|
addTask(task: TaskQueueItem): Promise<any>;
|
|
37
40
|
getQueueStatus(userId: string): {
|