koishi-plugin-aka-ai-generator 0.8.8 → 0.8.9
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.d.ts +1 -0
- package/lib/index.js +65 -6
- package/lib/services/UserManager.d.ts +1 -0
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -1636,6 +1636,39 @@ var UserManager = class {
|
|
|
1636
1636
|
return { allowed: true, reservationId };
|
|
1637
1637
|
});
|
|
1638
1638
|
}
|
|
1639
|
+
// 只记录调用次数,不扣减配额(用于管理员和平台免配额用户)
|
|
1640
|
+
async recordUsageOnly(userId, userName, commandName, numImages) {
|
|
1641
|
+
await this.loadUsersData();
|
|
1642
|
+
return await this.dataLock.acquire(async () => {
|
|
1643
|
+
if (!this.usersCache) {
|
|
1644
|
+
this.logger.error("recordUsageOnly: usersCache 为空,这不应该发生");
|
|
1645
|
+
this.usersCache = {};
|
|
1646
|
+
}
|
|
1647
|
+
let userData = this.usersCache[userId];
|
|
1648
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1649
|
+
if (!userData) {
|
|
1650
|
+
userData = {
|
|
1651
|
+
userId,
|
|
1652
|
+
userName: userName || userId,
|
|
1653
|
+
totalUsageCount: 0,
|
|
1654
|
+
dailyUsageCount: 0,
|
|
1655
|
+
lastDailyReset: now,
|
|
1656
|
+
purchasedCount: 0,
|
|
1657
|
+
remainingPurchasedCount: 0,
|
|
1658
|
+
donationCount: 0,
|
|
1659
|
+
donationAmount: 0,
|
|
1660
|
+
lastUsed: now,
|
|
1661
|
+
createdAt: now
|
|
1662
|
+
};
|
|
1663
|
+
this.usersCache[userId] = userData;
|
|
1664
|
+
}
|
|
1665
|
+
userData.totalUsageCount += numImages;
|
|
1666
|
+
userData.lastUsed = now;
|
|
1667
|
+
await this.saveUsersDataInternal();
|
|
1668
|
+
this.logger.debug("recordUsageOnly: 仅记录调用次数", { userId, userName, commandName, numImages, totalUsageCount: userData.totalUsageCount });
|
|
1669
|
+
return userData;
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1639
1672
|
// 扣减额度并记录使用
|
|
1640
1673
|
async consumeQuota(userId, userName, commandName, numImages, config) {
|
|
1641
1674
|
await this.loadUsersData();
|
|
@@ -1898,6 +1931,7 @@ var Config = import_koishi2.Schema.intersect([
|
|
|
1898
1931
|
// ===== 6. 限流与配额 =====
|
|
1899
1932
|
import_koishi2.Schema.object({
|
|
1900
1933
|
dailyFreeLimit: import_koishi2.Schema.number().default(5).min(1).max(100).description("每日免费调用次数"),
|
|
1934
|
+
unlimitedPlatforms: import_koishi2.Schema.array(import_koishi2.Schema.string()).default(["lark"]).description("不受配额限制的平台列表(如 lark, onebot, discord 等)"),
|
|
1901
1935
|
rateLimitWindow: import_koishi2.Schema.number().default(300).min(60).max(3600).description("限流时间窗口(秒)"),
|
|
1902
1936
|
rateLimitMax: import_koishi2.Schema.number().default(3).min(1).max(20).description("限流窗口内最大调用次数")
|
|
1903
1937
|
}).description("🚦 限流与配额"),
|
|
@@ -2090,11 +2124,19 @@ function apply(ctx, config) {
|
|
|
2090
2124
|
return input || null;
|
|
2091
2125
|
}
|
|
2092
2126
|
__name(getPromptInput, "getPromptInput");
|
|
2093
|
-
function buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config2) {
|
|
2094
|
-
|
|
2127
|
+
function buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config2, platform) {
|
|
2128
|
+
const isAdmin = userManager.isAdmin(userData.userId, config2);
|
|
2129
|
+
const isPlatformExempt = platform && config2.unlimitedPlatforms?.includes(platform);
|
|
2130
|
+
if (isAdmin) {
|
|
2095
2131
|
return `📊 使用统计 [管理员]
|
|
2096
2132
|
用户:${userData.userName}
|
|
2097
2133
|
总调用次数:${userData.totalUsageCount}次
|
|
2134
|
+
状态:无限制使用`;
|
|
2135
|
+
}
|
|
2136
|
+
if (isPlatformExempt) {
|
|
2137
|
+
return `📊 使用统计
|
|
2138
|
+
用户:${userData.userName}
|
|
2139
|
+
总调用次数:${userData.totalUsageCount}次
|
|
2098
2140
|
状态:无限制使用`;
|
|
2099
2141
|
}
|
|
2100
2142
|
const remainingToday = Math.max(0, config2.dailyFreeLimit - userData.dailyUsageCount);
|
|
@@ -2118,8 +2160,23 @@ function apply(ctx, config) {
|
|
|
2118
2160
|
async function recordUserUsage(session, commandName, numImages = 1, sendStatsImmediately = true) {
|
|
2119
2161
|
const userId = session.userId;
|
|
2120
2162
|
const userName = session.username || session.userId || "未知用户";
|
|
2163
|
+
const platform = session.platform;
|
|
2121
2164
|
if (!userId) return;
|
|
2122
|
-
const
|
|
2165
|
+
const isPlatformExempt = platform && config.unlimitedPlatforms?.includes(platform);
|
|
2166
|
+
const isAdmin = userManager.isAdmin(userId, config);
|
|
2167
|
+
let userData;
|
|
2168
|
+
let consumptionType = "free";
|
|
2169
|
+
let freeUsed = 0;
|
|
2170
|
+
let purchasedUsed = 0;
|
|
2171
|
+
if (isAdmin || isPlatformExempt) {
|
|
2172
|
+
userData = await userManager.recordUsageOnly(userId, userName, commandName, numImages);
|
|
2173
|
+
} else {
|
|
2174
|
+
const result = await userManager.consumeQuota(userId, userName, commandName, numImages, config);
|
|
2175
|
+
userData = result.userData;
|
|
2176
|
+
consumptionType = result.consumptionType;
|
|
2177
|
+
freeUsed = result.freeUsed;
|
|
2178
|
+
purchasedUsed = result.purchasedUsed;
|
|
2179
|
+
}
|
|
2123
2180
|
logger.info("用户调用记录", {
|
|
2124
2181
|
userId,
|
|
2125
2182
|
userName: userData.userName,
|
|
@@ -2131,11 +2188,13 @@ function apply(ctx, config) {
|
|
|
2131
2188
|
totalUsageCount: userData.totalUsageCount,
|
|
2132
2189
|
dailyUsageCount: userData.dailyUsageCount,
|
|
2133
2190
|
remainingPurchasedCount: userData.remainingPurchasedCount,
|
|
2134
|
-
isAdmin
|
|
2191
|
+
isAdmin,
|
|
2192
|
+
isPlatformExempt,
|
|
2193
|
+
platform
|
|
2135
2194
|
});
|
|
2136
2195
|
if (sendStatsImmediately) {
|
|
2137
2196
|
try {
|
|
2138
|
-
const statsMessage = buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config);
|
|
2197
|
+
const statsMessage = buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config, platform);
|
|
2139
2198
|
await session.send(statsMessage);
|
|
2140
2199
|
} catch (error) {
|
|
2141
2200
|
logger.warn("发送统计信息失败", { userId, error: sanitizeError(error) });
|
|
@@ -2143,7 +2202,7 @@ function apply(ctx, config) {
|
|
|
2143
2202
|
} else {
|
|
2144
2203
|
setImmediate(async () => {
|
|
2145
2204
|
try {
|
|
2146
|
-
const statsMessage = buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config);
|
|
2205
|
+
const statsMessage = buildStatsMessage(userData, numImages, consumptionType, freeUsed, purchasedUsed, config, platform);
|
|
2147
2206
|
await session.send(statsMessage);
|
|
2148
2207
|
logger.debug("统计信息已异步发送", { userId, commandName });
|
|
2149
2208
|
} catch (error) {
|
|
@@ -130,6 +130,7 @@ export declare class UserManager {
|
|
|
130
130
|
message?: string;
|
|
131
131
|
reservationId?: string;
|
|
132
132
|
}>;
|
|
133
|
+
recordUsageOnly(userId: string, userName: string, commandName: string, numImages: number): Promise<UserData>;
|
|
133
134
|
consumeQuota(userId: string, userName: string, commandName: string, numImages: number, config: Config): Promise<{
|
|
134
135
|
userData: UserData;
|
|
135
136
|
consumptionType: 'free' | 'purchased' | 'mixed';
|