feat(moderation): normalize JSON response handling and enhance test coverage for moderation analysis

This commit is contained in:
MythEclipse
2026-05-21 03:52:51 +07:00
parent 419018ab0c
commit 5588ece6c7
3 changed files with 78 additions and 4 deletions
+32 -2
View File
@@ -179,8 +179,8 @@ importers:
specifier: ^25.0.1
version: 25.8.0
discord.js-selfbot-v13:
specifier: workspace:*
version: link:../discord.js-selfbot-v13
specifier: ^3.7.1
version: 3.7.1
pkg-pr-new:
specifier: ^0.0.62
version: 0.0.62
@@ -2370,6 +2370,11 @@ packages:
discord-api-types@0.38.47:
resolution: {integrity: sha512-XgXQodHQBAE6kfD7kMvVo30863iHX1LHSqNq6MGUTDwIFCCvHva13+rwxyxVXDqudyApMNAd32PGjgVETi5rjA==}
discord.js-selfbot-v13@3.7.1:
resolution: {integrity: sha512-cq5AW/CVvNIUVTSBdZmhsob7v+wjxnkFjuNULcxBXvxutVBnSZqZupsT/9CDtdnT71iKUn9N8GGL6GPg9aZlGA==}
engines: {node: '>=20.18'}
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
dmd@4.0.6:
resolution: {integrity: sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==}
engines: {node: '>=8'}
@@ -6376,6 +6381,31 @@ snapshots:
discord-api-types@0.38.47: {}
discord.js-selfbot-v13@3.7.1:
dependencies:
'@discordjs/builders': 1.14.1
'@discordjs/collection': 2.1.1
'@sapphire/async-queue': 1.5.5
'@sapphire/shapeshift': 4.0.0
discord-api-types: 0.38.47
fetch-cookie: 3.2.0
find-process: 2.1.1
otplib: 12.0.1
prism-media: 1.3.5
qrcode: 1.5.4
tough-cookie: 5.1.2
tree-kill: 1.2.2
undici: 7.25.0
werift-rtp: 0.8.8
ws: 8.20.1
transitivePeerDependencies:
- '@discordjs/opus'
- bufferutil
- ffmpeg-static
- node-opus
- opusscript
- utf-8-validate
dmd@4.0.6:
dependencies:
array-back: 4.0.2
+10 -1
View File
@@ -19,7 +19,16 @@ const openai = new OpenAI({
? await response.text()
: JSON.stringify(await response.json());
return new Response(body, {
let normalizedBody = body;
if (response.ok !== false) {
try {
JSON.parse(body);
} catch {
normalizedBody = JSON.stringify(extractJson(body));
}
}
return new Response(normalizedBody, {
status: response.status ?? 200,
headers: { "Content-Type": "application/json" },
});
+36 -1
View File
@@ -481,7 +481,7 @@ describe("runModerationAnalysis", () => {
).rejects.toThrow(/500/);
});
it("parses first JSON object when provider appends extra JSON", async () => {
it("parses first JSON object when provider appends extra text to message content", async () => {
const moderationJson = JSON.stringify({
results: [
{
@@ -517,6 +517,41 @@ describe("runModerationAnalysis", () => {
expect(result.results[0].messageId).toBe("m1");
});
it("normalizes first JSON object when provider appends extra text to HTTP body", async () => {
const mockResponse = {
choices: [
{
message: {
content: JSON.stringify({
results: [
{
message_id: "m1",
status: "clean",
flags: [],
score: 0.1,
analysis: "OK",
},
],
}),
},
},
],
};
global.fetch = vi.fn().mockResolvedValue({
ok: true,
text: async () => `${JSON.stringify(mockResponse)}\nextra`,
});
const result = await runModerationAnalysis({
targets: [createMessageRecord()],
contextText: "test context",
});
expect(result.results).toHaveLength(1);
expect(result.results[0].messageId).toBe("m1");
});
it("throws on missing choices in response", async () => {
global.fetch = vi.fn().mockResolvedValue({
ok: true,