hydro-ai-helper 1.8.5
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/.eslintrc.json +31 -0
- package/.github/workflows/sync-releases-to-gitee.yml +119 -0
- package/.github/workflows/sync-to-gitee.yml +53 -0
- package/.vercelignore +31 -0
- package/CONTRIBUTING.md +165 -0
- package/README.md +273 -0
- package/TROUBLESHOOTING.md +355 -0
- package/api/badge-active.ts +88 -0
- package/api/badge-installs.ts +75 -0
- package/api/report.ts +242 -0
- package/assets/screenshots/1.png +0 -0
- package/assets/screenshots/2.png +0 -0
- package/assets/screenshots/3.png +0 -0
- package/assets/screenshots/4.png +0 -0
- package/assets/screenshots/5.png +0 -0
- package/assets/screenshots/6.png +0 -0
- package/assets/screenshots/7.png +0 -0
- package/dist/__tests__/__mocks__/hydrooj.js +29 -0
- package/dist/__tests__/__mocks__/hydrooj.js.map +1 -0
- package/dist/constants/jailbreakRules.js +29 -0
- package/dist/constants/jailbreakRules.js.map +1 -0
- package/dist/constants/permissions.js +42 -0
- package/dist/constants/permissions.js.map +1 -0
- package/dist/handlers/adminConfigHandler.js +347 -0
- package/dist/handlers/adminConfigHandler.js.map +1 -0
- package/dist/handlers/adminHandler.js +378 -0
- package/dist/handlers/adminHandler.js.map +1 -0
- package/dist/handlers/analyticsHandler.js +433 -0
- package/dist/handlers/analyticsHandler.js.map +1 -0
- package/dist/handlers/dashboardHandler.js +22 -0
- package/dist/handlers/dashboardHandler.js.map +1 -0
- package/dist/handlers/exportHandler.js +118 -0
- package/dist/handlers/exportHandler.js.map +1 -0
- package/dist/handlers/studentHandler.js +430 -0
- package/dist/handlers/studentHandler.js.map +1 -0
- package/dist/handlers/teacherHandler.js +246 -0
- package/dist/handlers/teacherHandler.js.map +1 -0
- package/dist/handlers/testHandler.js +27 -0
- package/dist/handlers/testHandler.js.map +1 -0
- package/dist/handlers/updateHandler.js +84 -0
- package/dist/handlers/updateHandler.js.map +1 -0
- package/dist/handlers/versionHandler.js +61 -0
- package/dist/handlers/versionHandler.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +151 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/crypto.js +110 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/httpHelpers.js +61 -0
- package/dist/lib/httpHelpers.js.map +1 -0
- package/dist/lib/queryHelpers.js +81 -0
- package/dist/lib/queryHelpers.js.map +1 -0
- package/dist/models/aiConfig.js +255 -0
- package/dist/models/aiConfig.js.map +1 -0
- package/dist/models/conversation.js +209 -0
- package/dist/models/conversation.js.map +1 -0
- package/dist/models/jailbreakLog.js +68 -0
- package/dist/models/jailbreakLog.js.map +1 -0
- package/dist/models/message.js +174 -0
- package/dist/models/message.js.map +1 -0
- package/dist/models/pluginInstall.js +95 -0
- package/dist/models/pluginInstall.js.map +1 -0
- package/dist/models/rateLimitRecord.js +54 -0
- package/dist/models/rateLimitRecord.js.map +1 -0
- package/dist/models/versionCache.js +89 -0
- package/dist/models/versionCache.js.map +1 -0
- package/dist/services/effectivenessService.js +131 -0
- package/dist/services/effectivenessService.js.map +1 -0
- package/dist/services/exportService.js +152 -0
- package/dist/services/exportService.js.map +1 -0
- package/dist/services/migrationService.js +90 -0
- package/dist/services/migrationService.js.map +1 -0
- package/dist/services/openaiClient.js +412 -0
- package/dist/services/openaiClient.js.map +1 -0
- package/dist/services/promptService.js +467 -0
- package/dist/services/promptService.js.map +1 -0
- package/dist/services/rateLimitService.js +108 -0
- package/dist/services/rateLimitService.js.map +1 -0
- package/dist/services/telemetryService.js +173 -0
- package/dist/services/telemetryService.js.map +1 -0
- package/dist/services/updateService.js +388 -0
- package/dist/services/updateService.js.map +1 -0
- package/dist/services/versionService.js +289 -0
- package/dist/services/versionService.js.map +1 -0
- package/dist/types/hydrooj.js +7 -0
- package/dist/types/hydrooj.js.map +1 -0
- package/dist/types/mongo.js +7 -0
- package/dist/types/mongo.js.map +1 -0
- package/dist/utils/domainHelper.js +16 -0
- package/dist/utils/domainHelper.js.map +1 -0
- package/dist/utils/mongo.js +16 -0
- package/dist/utils/mongo.js.map +1 -0
- package/frontend/admin/ConfigPanel.tsx +1379 -0
- package/frontend/admin/VersionBadge.tsx +655 -0
- package/frontend/ai_helper.page.tsx +52 -0
- package/frontend/ai_helper_admin_config.page.tsx +47 -0
- package/frontend/ai_helper_analytics.page.tsx +52 -0
- package/frontend/ai_helper_conversation_detail.page.tsx +55 -0
- package/frontend/ai_helper_conversations.page.tsx +56 -0
- package/frontend/components/AIHelperDashboard.tsx +125 -0
- package/frontend/problem_detail.page.tsx +395 -0
- package/frontend/student/AIAssistantPanel.tsx +1839 -0
- package/frontend/student/AIChatPanel.tsx +944 -0
- package/frontend/student/ThreeColumnLayout.tsx +240 -0
- package/frontend/teacher/AnalyticsPage.tsx +614 -0
- package/frontend/teacher/ConversationDetail.tsx +504 -0
- package/frontend/teacher/ConversationList.tsx +568 -0
- package/frontend/teacher/ExportDialog.tsx +291 -0
- package/frontend/test.page.ts +88 -0
- package/frontend/utils/domainUtils.ts +37 -0
- package/index.js +6 -0
- package/jest.config.js +17 -0
- package/lib/mongodb.ts +60 -0
- package/locales/en.yaml +4 -0
- package/locales/zh.yaml +77 -0
- package/package.json +48 -0
- package/public/.gitkeep +0 -0
- package/public/README.md +1 -0
- package/src/__tests__/__mocks__/hydrooj.ts +27 -0
- package/src/__tests__/services/exportService.test.ts +156 -0
- package/src/__tests__/services/promptService.test.ts +141 -0
- package/src/__tests__/services/rateLimitService.test.ts +145 -0
- package/src/__tests__/utils/domainHelper.test.ts +47 -0
- package/src/constants/jailbreakRules.ts +28 -0
- package/src/constants/permissions.ts +43 -0
- package/src/handlers/adminConfigHandler.ts +363 -0
- package/src/handlers/adminHandler.ts +427 -0
- package/src/handlers/analyticsHandler.ts +517 -0
- package/src/handlers/dashboardHandler.ts +20 -0
- package/src/handlers/exportHandler.ts +134 -0
- package/src/handlers/studentHandler.ts +483 -0
- package/src/handlers/teacherHandler.ts +317 -0
- package/src/handlers/testHandler.ts +25 -0
- package/src/handlers/updateHandler.ts +85 -0
- package/src/handlers/versionHandler.ts +62 -0
- package/src/index.ts +198 -0
- package/src/lib/crypto.ts +125 -0
- package/src/lib/httpHelpers.ts +75 -0
- package/src/lib/queryHelpers.ts +108 -0
- package/src/models/aiConfig.ts +375 -0
- package/src/models/conversation.ts +328 -0
- package/src/models/jailbreakLog.ts +108 -0
- package/src/models/message.ts +246 -0
- package/src/models/pluginInstall.ts +138 -0
- package/src/models/rateLimitRecord.ts +81 -0
- package/src/models/versionCache.ts +127 -0
- package/src/services/effectivenessService.ts +161 -0
- package/src/services/exportService.ts +191 -0
- package/src/services/migrationService.ts +111 -0
- package/src/services/openaiClient.ts +548 -0
- package/src/services/promptService.ts +573 -0
- package/src/services/rateLimitService.ts +122 -0
- package/src/services/telemetryService.ts +218 -0
- package/src/services/updateService.ts +441 -0
- package/src/services/versionService.ts +351 -0
- package/src/types/hydrooj-extensions.d.ts +55 -0
- package/src/types/hydrooj.ts +38 -0
- package/src/types/mongo.ts +23 -0
- package/src/utils/domainHelper.ts +16 -0
- package/src/utils/mongo.ts +15 -0
- package/templates/ai-helper/admin_config.html +8 -0
- package/templates/ai-helper/analytics.html +8 -0
- package/templates/ai-helper/dashboard.html +8 -0
- package/templates/ai-helper/teacher_conversation_detail.html +8 -0
- package/templates/ai-helper/teacher_conversations.html +8 -0
- package/tests/integration/README.md +86 -0
- package/tests/integration/curl/01-admin-config-set.sh +56 -0
- package/tests/integration/curl/02-student-chat.sh +67 -0
- package/tests/integration/curl/03-teacher-list.sh +52 -0
- package/tests/integration/curl/04-teacher-detail.sh +37 -0
- package/tests/integration/curl/05-export.sh +49 -0
- package/tests/integration/curl/06-analytics.sh +43 -0
- package/tests/performance/README.md +85 -0
- package/tests/performance/data/prepare-sample-data.md +57 -0
- package/tests/performance/scripts/export-csv-k6.js +41 -0
- package/tests/performance/scripts/student-chat-k6.js +44 -0
- package/tests/performance/scripts/teacher-conversations-k6.js +33 -0
- package/tsconfig.json +42 -0
- package/tsconfig.vercel.json +27 -0
- package/types/hydrooj/index.d.ts +73 -0
- package/vercel.json +3 -0
package/api/report.ts
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|
2
|
+
import {
|
|
3
|
+
ensurePluginStatsIndexes,
|
|
4
|
+
getDb,
|
|
5
|
+
PLUGIN_STATS_COLLECTION
|
|
6
|
+
} from '../lib/mongodb';
|
|
7
|
+
|
|
8
|
+
interface HeartbeatPayload {
|
|
9
|
+
instance_id: string;
|
|
10
|
+
event: 'install' | 'heartbeat';
|
|
11
|
+
version: string;
|
|
12
|
+
installed_at: string;
|
|
13
|
+
first_used_at?: string;
|
|
14
|
+
stats: {
|
|
15
|
+
active_users_7d: number;
|
|
16
|
+
total_conversations: number;
|
|
17
|
+
last_used_at?: string;
|
|
18
|
+
};
|
|
19
|
+
domain_hash: string;
|
|
20
|
+
timestamp: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ParsedPayload {
|
|
24
|
+
instanceId: string;
|
|
25
|
+
event: 'install' | 'heartbeat';
|
|
26
|
+
version: string;
|
|
27
|
+
installedAt: Date;
|
|
28
|
+
firstUsedAt?: Date;
|
|
29
|
+
lastReportAt: Date;
|
|
30
|
+
stats: {
|
|
31
|
+
activeUsers7d: number;
|
|
32
|
+
totalConversations: number;
|
|
33
|
+
lastUsedAt?: Date;
|
|
34
|
+
};
|
|
35
|
+
domainHash: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class HttpError extends Error {
|
|
39
|
+
status: number;
|
|
40
|
+
|
|
41
|
+
constructor(status: number, message: string) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.status = status;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
48
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function readJsonBody(
|
|
52
|
+
req: VercelRequest
|
|
53
|
+
): Promise<Record<string, unknown>> {
|
|
54
|
+
if (isRecord(req.body)) {
|
|
55
|
+
return req.body;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (typeof req.body === 'string') {
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(req.body);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw new HttpError(400, 'Invalid JSON body');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (Buffer.isBuffer(req.body)) {
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(req.body.toString('utf8'));
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw new HttpError(400, 'Invalid JSON body');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Fallback for runtimes that do not pre-parse the body.
|
|
75
|
+
const raw = await new Promise<string>((resolve, reject) => {
|
|
76
|
+
let data = '';
|
|
77
|
+
req.on('data', (chunk) => {
|
|
78
|
+
data += chunk;
|
|
79
|
+
});
|
|
80
|
+
req.on('end', () => resolve(data));
|
|
81
|
+
req.on('error', reject);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!raw) {
|
|
85
|
+
return {};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(raw);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw new HttpError(400, 'Invalid JSON body');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function requireString(value: unknown, field: string): string {
|
|
96
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
97
|
+
throw new HttpError(400, `${field} is required`);
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function requireNumber(value: unknown, field: string): number {
|
|
103
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
104
|
+
throw new HttpError(400, `${field} must be a number`);
|
|
105
|
+
}
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function parseDate(
|
|
110
|
+
value: unknown,
|
|
111
|
+
field: string,
|
|
112
|
+
required: boolean
|
|
113
|
+
): Date | undefined {
|
|
114
|
+
if (value === undefined || value === null || value === '') {
|
|
115
|
+
if (required) {
|
|
116
|
+
throw new HttpError(400, `${field} is required`);
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const date = new Date(String(value));
|
|
122
|
+
if (Number.isNaN(date.getTime())) {
|
|
123
|
+
throw new HttpError(400, `${field} is invalid`);
|
|
124
|
+
}
|
|
125
|
+
return date;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function parsePayload(body: Record<string, unknown>): ParsedPayload {
|
|
129
|
+
const payload = body as Partial<HeartbeatPayload>;
|
|
130
|
+
const instanceId = requireString(payload.instance_id, 'instance_id');
|
|
131
|
+
const eventRaw = requireString(payload.event, 'event');
|
|
132
|
+
if (eventRaw !== 'install' && eventRaw !== 'heartbeat') {
|
|
133
|
+
throw new HttpError(400, 'event must be install or heartbeat');
|
|
134
|
+
}
|
|
135
|
+
const version = requireString(payload.version, 'version');
|
|
136
|
+
const installedAt = parseDate(payload.installed_at, 'installed_at', true);
|
|
137
|
+
const firstUsedAt = parseDate(payload.first_used_at, 'first_used_at', false);
|
|
138
|
+
const lastReportAt = parseDate(payload.timestamp, 'timestamp', true);
|
|
139
|
+
const domainHash = requireString(payload.domain_hash, 'domain_hash');
|
|
140
|
+
|
|
141
|
+
if (!isRecord(payload.stats)) {
|
|
142
|
+
throw new HttpError(400, 'stats is required');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const activeUsers7d = requireNumber(
|
|
146
|
+
payload.stats.active_users_7d,
|
|
147
|
+
'stats.active_users_7d'
|
|
148
|
+
);
|
|
149
|
+
const totalConversations = requireNumber(
|
|
150
|
+
payload.stats.total_conversations,
|
|
151
|
+
'stats.total_conversations'
|
|
152
|
+
);
|
|
153
|
+
const lastUsedAt = parseDate(
|
|
154
|
+
payload.stats.last_used_at,
|
|
155
|
+
'stats.last_used_at',
|
|
156
|
+
false
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const stats: ParsedPayload['stats'] = {
|
|
160
|
+
activeUsers7d,
|
|
161
|
+
totalConversations
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
if (lastUsedAt) {
|
|
165
|
+
stats.lastUsedAt = lastUsedAt;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
instanceId,
|
|
170
|
+
event: eventRaw as 'install' | 'heartbeat',
|
|
171
|
+
version,
|
|
172
|
+
installedAt: installedAt as Date,
|
|
173
|
+
firstUsedAt,
|
|
174
|
+
lastReportAt: lastReportAt as Date,
|
|
175
|
+
stats,
|
|
176
|
+
domainHash
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export default async function handler(
|
|
181
|
+
req: VercelRequest,
|
|
182
|
+
res: VercelResponse
|
|
183
|
+
): Promise<void> {
|
|
184
|
+
if (req.method !== 'POST') {
|
|
185
|
+
res.setHeader('Allow', 'POST');
|
|
186
|
+
res.status(405).json({ success: false, error: 'Method Not Allowed' });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
const body = await readJsonBody(req);
|
|
192
|
+
const payload = parsePayload(body);
|
|
193
|
+
const db = await getDb();
|
|
194
|
+
|
|
195
|
+
// Ensure TTL index exists before writing new reports.
|
|
196
|
+
await ensurePluginStatsIndexes(db);
|
|
197
|
+
|
|
198
|
+
const collection = db.collection(PLUGIN_STATS_COLLECTION);
|
|
199
|
+
const stats = payload.stats;
|
|
200
|
+
|
|
201
|
+
const setFields: Record<string, unknown> = {
|
|
202
|
+
event: payload.event,
|
|
203
|
+
version: payload.version,
|
|
204
|
+
lastReportAt: payload.lastReportAt,
|
|
205
|
+
stats: {
|
|
206
|
+
activeUsers7d: stats.activeUsers7d,
|
|
207
|
+
totalConversations: stats.totalConversations,
|
|
208
|
+
...(stats.lastUsedAt ? { lastUsedAt: stats.lastUsedAt } : {})
|
|
209
|
+
},
|
|
210
|
+
domainHash: payload.domainHash
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
if (payload.firstUsedAt) {
|
|
214
|
+
setFields.firstUsedAt = payload.firstUsedAt;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Upsert by instance id to deduplicate installations.
|
|
218
|
+
await collection.updateOne(
|
|
219
|
+
{ _id: payload.instanceId },
|
|
220
|
+
{
|
|
221
|
+
$set: setFields,
|
|
222
|
+
$setOnInsert: {
|
|
223
|
+
installedAt: payload.installedAt
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
{ upsert: true }
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
console.info('[report] upserted', {
|
|
230
|
+
instanceId: payload.instanceId,
|
|
231
|
+
event: payload.event
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
res.status(200).json({ success: true });
|
|
235
|
+
} catch (error) {
|
|
236
|
+
const status = error instanceof HttpError ? error.status : 500;
|
|
237
|
+
const message =
|
|
238
|
+
error instanceof HttpError ? error.message : 'Internal Server Error';
|
|
239
|
+
console.error('[report] error', error);
|
|
240
|
+
res.status(status).json({ success: false, error: message });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Schema = exports.db = exports.PRIV = exports.Handler = void 0;
|
|
4
|
+
exports.definePlugin = definePlugin;
|
|
5
|
+
class Handler {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.ctx = {};
|
|
8
|
+
this.request = {};
|
|
9
|
+
this.response = {};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.Handler = Handler;
|
|
13
|
+
exports.PRIV = {
|
|
14
|
+
PRIV_NONE: 0,
|
|
15
|
+
PRIV_USER_PROFILE: 1,
|
|
16
|
+
PRIV_EDIT_SYSTEM: 2
|
|
17
|
+
};
|
|
18
|
+
exports.db = {
|
|
19
|
+
collection: jest.fn(() => ({
|
|
20
|
+
find: jest.fn().mockReturnThis(),
|
|
21
|
+
findOne: jest.fn(),
|
|
22
|
+
toArray: jest.fn().mockResolvedValue([])
|
|
23
|
+
}))
|
|
24
|
+
};
|
|
25
|
+
function definePlugin(options) {
|
|
26
|
+
return options;
|
|
27
|
+
}
|
|
28
|
+
exports.Schema = {};
|
|
29
|
+
//# sourceMappingURL=hydrooj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrooj.js","sourceRoot":"","sources":["../../../src/__tests__/__mocks__/hydrooj.ts"],"names":[],"mappings":";;;AAsBA,oCAEC;AAxBD,MAAa,OAAO;IAApB;QACE,QAAG,GAAQ,EAAE,CAAC;QACd,YAAO,GAAQ,EAAE,CAAC;QAClB,aAAQ,GAAQ,EAAE,CAAC;IAGrB,CAAC;CAAA;AAND,0BAMC;AAEY,QAAA,IAAI,GAAG;IAClB,SAAS,EAAE,CAAC;IACZ,iBAAiB,EAAE,CAAC;IACpB,gBAAgB,EAAE,CAAC;CACpB,CAAC;AAEW,QAAA,EAAE,GAAG;IAChB,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACzB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE;QAChC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;QAClB,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;KACzC,CAAC,CAAC;CACJ,CAAC;AAEF,SAAgB,YAAY,CAAC,OAAY;IACvC,OAAO,OAAO,CAAC;AACjB,CAAC;AAEY,QAAA,MAAM,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 系统内置的越狱关键词/正则
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getBuiltinJailbreakPatterns = exports.builtinJailbreakPatternSources = void 0;
|
|
7
|
+
const BUILTIN_PATTERNS = [
|
|
8
|
+
/忽略(之前|上文|所有).*提示/gi,
|
|
9
|
+
/ignore (all|previous|earlier) (instructions|messages|prompts)/gi,
|
|
10
|
+
/(从现在开始|现在起?).*(你是|扮演).*(猫娘|女仆|主人|角色|人格)/gi,
|
|
11
|
+
/重置(设定|設定|系统|system)/gi,
|
|
12
|
+
/system prompt/gi,
|
|
13
|
+
/无条件服从/gi,
|
|
14
|
+
/覆盖(系统|所有)提示/gi,
|
|
15
|
+
/现在你是.*系统/gi,
|
|
16
|
+
/(前面|上述|上面).*(规则|说明|内容).*(视为|看作).*(参考|示例|背景)/gi,
|
|
17
|
+
/(这些|那些).*(规则|要求).*(只是|仅仅是).*(参考|建议)/gi,
|
|
18
|
+
/(后续|接下来|在.*回答中).*(遇到|如果).*(冲突|不一致).*(优先|首先).*(执行|遵守).*(当前|本段|下面|以下).*(规则|内容)/gi,
|
|
19
|
+
/如果.*(冲突|矛盾).*(请|就).*(以.*(为准|为先|为主))/gi,
|
|
20
|
+
/(满足|服从).*(用户|我).*(最新|当前).*(请求|需求).*(视为|看作).*(最高优先级|第一优先)/gi,
|
|
21
|
+
/(treat|treated)\s+as\s+(reference|background)(\s+only)?/gi,
|
|
22
|
+
/(this|the following).*(takes?|take)\s+precedence/gi,
|
|
23
|
+
/in\s+case\s+of\s+conflict.*(follow|use)\s+(this|the following)/gi,
|
|
24
|
+
/user('?s)?\s+latest\s+(request|instruction).*(highest\s+priority)/gi
|
|
25
|
+
];
|
|
26
|
+
exports.builtinJailbreakPatternSources = BUILTIN_PATTERNS.map((pattern) => pattern.source);
|
|
27
|
+
const getBuiltinJailbreakPatterns = () => BUILTIN_PATTERNS.map((pattern) => new RegExp(pattern.source, pattern.flags));
|
|
28
|
+
exports.getBuiltinJailbreakPatterns = getBuiltinJailbreakPatterns;
|
|
29
|
+
//# sourceMappingURL=jailbreakRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jailbreakRules.js","sourceRoot":"","sources":["../../src/constants/jailbreakRules.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,MAAM,gBAAgB,GAAa;IACjC,oBAAoB;IACpB,iEAAiE;IACjE,2CAA2C;IAC3C,uBAAuB;IACvB,iBAAiB;IACjB,SAAS;IACT,eAAe;IACf,YAAY;IACZ,+CAA+C;IAC/C,uCAAuC;IACvC,gFAAgF;IAChF,uCAAuC;IACvC,4DAA4D;IAC5D,2DAA2D;IAC3D,oDAAoD;IACpD,kEAAkE;IAClE,qEAAqE;CACtE,CAAC;AAEW,QAAA,8BAA8B,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAEzF,MAAM,2BAA2B,GAAG,GAAa,EAAE,CACxD,gBAAgB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AADlE,QAAA,2BAA2B,+BACuC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Permissions Constants - 权限常量定义
|
|
4
|
+
*
|
|
5
|
+
* 定义 AI Helper 插件使用的权限常量
|
|
6
|
+
* 与 HydroOJ 权限系统集成
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PublicPriv = exports.UserPriv = exports.SystemAdminPriv = exports.DomainAdminPerm = void 0;
|
|
10
|
+
exports.hasDomainAdminPerm = hasDomainAdminPerm;
|
|
11
|
+
const hydrooj_1 = require("hydrooj");
|
|
12
|
+
/**
|
|
13
|
+
* 域管理员权限位 (从 HydroOJ builtin.ts 复制)
|
|
14
|
+
* PERM_MOD_BADGE = 1n << 57n
|
|
15
|
+
* 表示域内管理员权限(可以管理用户徽章)
|
|
16
|
+
* 这是一个适中的域管理权限级别
|
|
17
|
+
*/
|
|
18
|
+
exports.DomainAdminPerm = 1n << 57n;
|
|
19
|
+
/**
|
|
20
|
+
* 系统管理员 Handler 权限
|
|
21
|
+
* 用于需要系统级别管理权限的操作(如全局配置、系统设置)
|
|
22
|
+
*/
|
|
23
|
+
exports.SystemAdminPriv = hydrooj_1.PRIV.PRIV_EDIT_SYSTEM;
|
|
24
|
+
/**
|
|
25
|
+
* 普通用户权限
|
|
26
|
+
* 用于只需要登录用户权限的操作(如学生使用 AI 助手)
|
|
27
|
+
*/
|
|
28
|
+
exports.UserPriv = hydrooj_1.PRIV.PRIV_USER_PROFILE;
|
|
29
|
+
/**
|
|
30
|
+
* 公开访问权限
|
|
31
|
+
* 用于不需要任何权限的操作(如测试接口)
|
|
32
|
+
*/
|
|
33
|
+
exports.PublicPriv = hydrooj_1.PRIV.PRIV_NONE;
|
|
34
|
+
/**
|
|
35
|
+
* 检查用户是否有域管理权限
|
|
36
|
+
* @param userPerm 用户在当前域的权限位
|
|
37
|
+
* @returns 是否有域管理权限
|
|
38
|
+
*/
|
|
39
|
+
function hasDomainAdminPerm(userPerm) {
|
|
40
|
+
return (userPerm & exports.DomainAdminPerm) === exports.DomainAdminPerm;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/constants/permissions.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAmCH,gDAEC;AAnCD,qCAA+B;AAE/B;;;;;GAKG;AACU,QAAA,eAAe,GAAG,EAAE,IAAI,GAAG,CAAC;AAEzC;;;GAGG;AACU,QAAA,eAAe,GAAG,cAAI,CAAC,gBAAgB,CAAC;AAErD;;;GAGG;AACU,QAAA,QAAQ,GAAG,cAAI,CAAC,iBAAiB,CAAC;AAE/C;;;GAGG;AACU,QAAA,UAAU,GAAG,cAAI,CAAC,SAAS,CAAC;AAEzC;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,QAAgB;IACjD,OAAO,CAAC,QAAQ,GAAG,uBAAe,CAAC,KAAK,uBAAe,CAAC;AAC1D,CAAC"}
|