koishi-plugin-aka-ai-generator 0.4.4 → 0.5.1
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 +2 -0
- package/lib/index.js +68 -3
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface Config {
|
|
|
49
49
|
styles: StyleConfig[];
|
|
50
50
|
styleGroups?: Record<string, StyleGroupConfig>;
|
|
51
51
|
logLevel: 'info' | 'debug';
|
|
52
|
+
securityBlockWindow: number;
|
|
53
|
+
securityBlockWarningThreshold: number;
|
|
52
54
|
}
|
|
53
55
|
export interface RechargeRecord {
|
|
54
56
|
id: string;
|
package/lib/index.js
CHANGED
|
@@ -943,7 +943,10 @@ var Config = import_koishi.Schema.intersect([
|
|
|
943
943
|
logLevel: import_koishi.Schema.union([
|
|
944
944
|
import_koishi.Schema.const("info").description("普通信息"),
|
|
945
945
|
import_koishi.Schema.const("debug").description("完整的debug信息")
|
|
946
|
-
]).default("info").description("日志输出详细程度")
|
|
946
|
+
]).default("info").description("日志输出详细程度"),
|
|
947
|
+
// 安全策略拦截设置
|
|
948
|
+
securityBlockWindow: import_koishi.Schema.number().default(600).min(60).max(3600).description("安全策略拦截追踪时间窗口(秒),在此时间窗口内连续触发拦截会被记录"),
|
|
949
|
+
securityBlockWarningThreshold: import_koishi.Schema.number().default(3).min(1).max(10).description("安全策略拦截警示阈值,连续触发此次数拦截后将发送警示消息,再次触发将被扣除积分")
|
|
947
950
|
}),
|
|
948
951
|
// 自定义风格命令配置
|
|
949
952
|
import_koishi.Schema.object({
|
|
@@ -968,6 +971,8 @@ function apply(ctx, config) {
|
|
|
968
971
|
const logger = ctx.logger("aka-ai-generator");
|
|
969
972
|
const activeTasks = /* @__PURE__ */ new Map();
|
|
970
973
|
const rateLimitMap = /* @__PURE__ */ new Map();
|
|
974
|
+
const securityBlockMap = /* @__PURE__ */ new Map();
|
|
975
|
+
const securityWarningMap = /* @__PURE__ */ new Map();
|
|
971
976
|
const providerCache = /* @__PURE__ */ new Map();
|
|
972
977
|
function getProviderInstance(providerType, modelId) {
|
|
973
978
|
const cacheKey = `${providerType}:${modelId || "default"}`;
|
|
@@ -1393,6 +1398,40 @@ function apply(ctx, config) {
|
|
|
1393
1398
|
});
|
|
1394
1399
|
}
|
|
1395
1400
|
__name(recordUserUsage, "recordUserUsage");
|
|
1401
|
+
async function recordSecurityBlock(session, numImages = 1) {
|
|
1402
|
+
const userId = session.userId;
|
|
1403
|
+
if (!userId) return;
|
|
1404
|
+
if (isAdmin(userId)) {
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
const now = Date.now();
|
|
1408
|
+
const windowMs = config.securityBlockWindow * 1e3;
|
|
1409
|
+
const windowStart = now - windowMs;
|
|
1410
|
+
let blockTimestamps = securityBlockMap.get(userId) || [];
|
|
1411
|
+
blockTimestamps = blockTimestamps.filter((timestamp) => timestamp > windowStart);
|
|
1412
|
+
blockTimestamps.push(now);
|
|
1413
|
+
securityBlockMap.set(userId, blockTimestamps);
|
|
1414
|
+
const blockCount = blockTimestamps.length;
|
|
1415
|
+
const hasWarning = securityWarningMap.get(userId) || false;
|
|
1416
|
+
logger.info("安全策略拦截记录", {
|
|
1417
|
+
userId,
|
|
1418
|
+
blockCount,
|
|
1419
|
+
threshold: config.securityBlockWarningThreshold,
|
|
1420
|
+
hasWarning,
|
|
1421
|
+
numImages
|
|
1422
|
+
});
|
|
1423
|
+
if (blockCount >= config.securityBlockWarningThreshold && !hasWarning) {
|
|
1424
|
+
securityWarningMap.set(userId, true);
|
|
1425
|
+
await session.send(`⚠️ 安全策略警示
|
|
1426
|
+
您已连续${config.securityBlockWarningThreshold}次触发安全策略拦截,再次发送被拦截内容将被扣除积分`);
|
|
1427
|
+
logger.warn("用户收到安全策略警示", { userId, blockCount, threshold: config.securityBlockWarningThreshold });
|
|
1428
|
+
} else if (hasWarning) {
|
|
1429
|
+
const commandName = "安全策略拦截";
|
|
1430
|
+
await recordUserUsage(session, commandName, numImages);
|
|
1431
|
+
logger.warn("用户因安全策略拦截被扣除积分", { userId, numImages });
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
__name(recordSecurityBlock, "recordSecurityBlock");
|
|
1396
1435
|
async function getInputData(session, imgParam, mode) {
|
|
1397
1436
|
const collectedImages = [];
|
|
1398
1437
|
let collectedText = "";
|
|
@@ -1496,11 +1535,19 @@ function apply(ctx, config) {
|
|
|
1496
1535
|
new Promise(
|
|
1497
1536
|
(_, reject) => setTimeout(() => reject(new Error("命令执行超时")), config.commandTimeout * 1e3)
|
|
1498
1537
|
)
|
|
1499
|
-
]).catch((error) => {
|
|
1538
|
+
]).catch(async (error) => {
|
|
1500
1539
|
const userId = session.userId;
|
|
1501
1540
|
if (userId) activeTasks.delete(userId);
|
|
1502
1541
|
const sanitizedError = sanitizeError(error);
|
|
1503
1542
|
logger.error("图像处理超时或失败", { userId, error: sanitizedError });
|
|
1543
|
+
if (error?.message !== "命令执行超时") {
|
|
1544
|
+
const errorMessage = error?.message || "";
|
|
1545
|
+
const isSecurityBlock = errorMessage.includes("内容被安全策略拦截") || errorMessage.includes("内容被安全策略阻止") || errorMessage.includes("内容被阻止") || errorMessage.includes("被阻止") || errorMessage.includes("SAFETY") || errorMessage.includes("RECITATION");
|
|
1546
|
+
if (isSecurityBlock) {
|
|
1547
|
+
const imageCount = requestContext?.numImages || config.defaultNumImages;
|
|
1548
|
+
await recordSecurityBlock(session, imageCount);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1504
1551
|
const safeMessage = typeof error?.message === "string" ? sanitizeString(error.message) : "未知错误";
|
|
1505
1552
|
return error.message === "命令执行超时" ? "图像处理超时,请重试" : `图像处理失败:${safeMessage}`;
|
|
1506
1553
|
});
|
|
@@ -1589,6 +1636,11 @@ ${infoParts.join("\n")}`;
|
|
|
1589
1636
|
activeTasks.delete(userId);
|
|
1590
1637
|
const sanitizedError = sanitizeError(error);
|
|
1591
1638
|
logger.error("图像处理失败", { userId, error: sanitizedError });
|
|
1639
|
+
const errorMessage = error?.message || "";
|
|
1640
|
+
const isSecurityBlock = errorMessage.includes("内容被安全策略拦截") || errorMessage.includes("内容被安全策略阻止") || errorMessage.includes("内容被阻止") || errorMessage.includes("被阻止") || errorMessage.includes("SAFETY") || errorMessage.includes("RECITATION");
|
|
1641
|
+
if (isSecurityBlock) {
|
|
1642
|
+
await recordSecurityBlock(session, imageCount);
|
|
1643
|
+
}
|
|
1592
1644
|
if (error?.message) {
|
|
1593
1645
|
const safeMessage = sanitizeString(error.message);
|
|
1594
1646
|
return `图像处理失败:${safeMessage}`;
|
|
@@ -1755,6 +1807,11 @@ Prompt: ${prompt}`);
|
|
|
1755
1807
|
activeTasks.delete(userId);
|
|
1756
1808
|
const sanitizedError = sanitizeError(error);
|
|
1757
1809
|
logger.error("图片合成失败", { userId, error: sanitizedError });
|
|
1810
|
+
const errorMessage = error?.message || "";
|
|
1811
|
+
const isSecurityBlock = errorMessage.includes("内容被安全策略拦截") || errorMessage.includes("内容被安全策略阻止") || errorMessage.includes("内容被阻止") || errorMessage.includes("被阻止") || errorMessage.includes("SAFETY") || errorMessage.includes("RECITATION");
|
|
1812
|
+
if (isSecurityBlock) {
|
|
1813
|
+
await recordSecurityBlock(session, imageCount);
|
|
1814
|
+
}
|
|
1758
1815
|
if (error?.message) {
|
|
1759
1816
|
const safeMessage = sanitizeString(error.message);
|
|
1760
1817
|
return `图片合成失败:${safeMessage}`;
|
|
@@ -1765,11 +1822,19 @@ Prompt: ${prompt}`);
|
|
|
1765
1822
|
new Promise(
|
|
1766
1823
|
(_, reject) => setTimeout(() => reject(new Error("命令执行超时")), config.commandTimeout * 1e3)
|
|
1767
1824
|
)
|
|
1768
|
-
]).catch((error) => {
|
|
1825
|
+
]).catch(async (error) => {
|
|
1769
1826
|
const userId = session.userId;
|
|
1770
1827
|
if (userId) activeTasks.delete(userId);
|
|
1771
1828
|
const sanitizedError = sanitizeError(error);
|
|
1772
1829
|
logger.error("图片合成超时或失败", { userId, error: sanitizedError });
|
|
1830
|
+
if (error?.message !== "命令执行超时") {
|
|
1831
|
+
const errorMessage = error?.message || "";
|
|
1832
|
+
const isSecurityBlock = errorMessage.includes("内容被安全策略拦截") || errorMessage.includes("内容被安全策略阻止") || errorMessage.includes("内容被阻止") || errorMessage.includes("被阻止") || errorMessage.includes("SAFETY") || errorMessage.includes("RECITATION");
|
|
1833
|
+
if (isSecurityBlock) {
|
|
1834
|
+
const imageCount = options?.num || config.defaultNumImages;
|
|
1835
|
+
await recordSecurityBlock(session, imageCount);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1773
1838
|
const safeMessage = typeof error?.message === "string" ? sanitizeString(error.message) : "未知错误";
|
|
1774
1839
|
return error.message === "命令执行超时" ? "图片合成超时,请重试" : `图片合成失败:${safeMessage}`;
|
|
1775
1840
|
});
|