promptfoo 0.119.13 → 0.119.14
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/dist/package.json +28 -26
- package/dist/src/app/assets/index-eJ2lMe94.js +51 -0
- package/dist/src/app/assets/{source-map-support-Bnh0UQ2S.js → source-map-support-1v4oeb7P.js} +1 -1
- package/dist/src/app/assets/sync-CtLQRuC1.js +1 -0
- package/dist/src/app/assets/{vendor-charts-T60Uk0Z3.js → vendor-charts-DnVv66VV.js} +1 -1
- package/dist/src/app/assets/{vendor-markdown-DLig-KJh.js → vendor-markdown-DCpQIyMA.js} +1 -1
- package/dist/src/app/assets/{vendor-mui-core-5BLaiG3c.js → vendor-mui-core-Boqnpf9f.js} +1 -1
- package/dist/src/app/assets/{vendor-mui-icons-fn39Fu2e.js → vendor-mui-icons-B8MqoVbj.js} +1 -1
- package/dist/src/app/assets/vendor-mui-x-CGSS6QHF.js +45 -0
- package/dist/src/app/assets/{vendor-utils-DYBMEuwX.js → vendor-utils-DdfHIEy8.js} +1 -1
- package/dist/src/app/index.html +7 -7
- package/dist/src/assertions/guardrails.d.ts +1 -1
- package/dist/src/assertions/guardrails.js +18 -9
- package/dist/src/assertions/index.d.ts +1 -1
- package/dist/src/assertions/index.js +9 -3
- package/dist/src/assertions/searchRubric.d.ts +3 -0
- package/dist/src/assertions/searchRubric.js +18 -0
- package/dist/src/commands/eval.js +1 -1
- package/dist/src/commands/modelScan.d.ts +7 -1
- package/dist/src/commands/modelScan.js +121 -59
- package/dist/src/database/index.d.ts +6 -0
- package/dist/src/database/index.js +11 -0
- package/dist/src/database/tables.d.ts +46 -24
- package/dist/src/envars.d.ts +17 -0
- package/dist/src/generated/constants.js +1 -1
- package/dist/src/logger.d.ts +5 -0
- package/dist/src/logger.js +28 -0
- package/dist/src/main.js +17 -6
- package/dist/src/matchers.d.ts +1 -0
- package/dist/src/matchers.js +80 -0
- package/dist/src/models/eval.d.ts +2 -1
- package/dist/src/models/eval.js +44 -2
- package/dist/src/prompts/grading.d.ts +1 -0
- package/dist/src/prompts/grading.js +26 -1
- package/dist/src/prompts/index.d.ts +1 -0
- package/dist/src/prompts/index.js +4 -1
- package/dist/src/providers/adaline.gateway.js +2 -2
- package/dist/src/providers/anthropic/defaults.d.ts +1 -1
- package/dist/src/providers/anthropic/defaults.js +15 -0
- package/dist/src/providers/azure/chat.d.ts +3 -1
- package/dist/src/providers/azure/chat.js +16 -3
- package/dist/src/providers/azure/defaults.js +660 -141
- package/dist/src/providers/azure/responses.d.ts +5 -0
- package/dist/src/providers/azure/responses.js +33 -4
- package/dist/src/providers/azure/types.d.ts +4 -0
- package/dist/src/providers/bedrock/agents.d.ts +1 -1
- package/dist/src/providers/bedrock/agents.js +2 -2
- package/dist/src/providers/bedrock/base.d.ts +40 -0
- package/dist/src/providers/bedrock/base.js +171 -0
- package/dist/src/providers/bedrock/converse.d.ts +146 -0
- package/dist/src/providers/bedrock/converse.js +1044 -0
- package/dist/src/providers/bedrock/index.d.ts +1 -34
- package/dist/src/providers/bedrock/index.js +4 -159
- package/dist/src/providers/bedrock/knowledgeBase.d.ts +1 -1
- package/dist/src/providers/bedrock/knowledgeBase.js +2 -2
- package/dist/src/providers/bedrock/nova-sonic.d.ts +2 -1
- package/dist/src/providers/bedrock/nova-sonic.js +2 -2
- package/dist/src/providers/claude-agent-sdk.d.ts +58 -1
- package/dist/src/providers/claude-agent-sdk.js +22 -1
- package/dist/src/providers/defaults.js +4 -0
- package/dist/src/providers/github/defaults.js +6 -6
- package/dist/src/providers/google/types.d.ts +25 -0
- package/dist/src/providers/google/util.d.ts +2 -0
- package/dist/src/providers/google/vertex.js +78 -22
- package/dist/src/providers/{groq.d.ts → groq/chat.d.ts} +26 -20
- package/dist/src/providers/groq/chat.js +79 -0
- package/dist/src/providers/groq/index.d.ts +5 -0
- package/dist/src/providers/groq/index.js +24 -0
- package/dist/src/providers/groq/responses.d.ts +106 -0
- package/dist/src/providers/groq/responses.js +64 -0
- package/dist/src/providers/groq/types.d.ts +44 -0
- package/dist/src/providers/groq/types.js +3 -0
- package/dist/src/providers/groq/util.d.ts +15 -0
- package/dist/src/providers/groq/util.js +28 -0
- package/dist/src/providers/mcp/client.d.ts +8 -0
- package/dist/src/providers/mcp/client.js +60 -10
- package/dist/src/providers/mcp/types.d.ts +21 -0
- package/dist/src/providers/openai/chatkit-pool.d.ts +114 -0
- package/dist/src/providers/openai/chatkit-pool.js +548 -0
- package/dist/src/providers/openai/chatkit-types.d.ts +73 -0
- package/dist/src/providers/openai/chatkit-types.js +3 -0
- package/dist/src/providers/openai/chatkit.d.ts +76 -0
- package/dist/src/providers/openai/chatkit.js +879 -0
- package/dist/src/providers/openai/codex-sdk.d.ts +109 -0
- package/dist/src/providers/openai/codex-sdk.js +346 -0
- package/dist/src/providers/openai/defaults.d.ts +2 -0
- package/dist/src/providers/openai/defaults.js +10 -4
- package/dist/src/providers/registry.js +48 -9
- package/dist/src/providers/responses/types.d.ts +1 -1
- package/dist/src/providers/sagemaker.d.ts +2 -2
- package/dist/src/providers/webSearchUtils.d.ts +17 -0
- package/dist/src/providers/webSearchUtils.js +169 -0
- package/dist/src/providers/xai/chat.d.ts +61 -0
- package/dist/src/providers/xai/chat.js +68 -3
- package/dist/src/providers/xai/responses.d.ts +189 -0
- package/dist/src/providers/xai/responses.js +268 -0
- package/dist/src/redteam/constants/plugins.d.ts +1 -1
- package/dist/src/redteam/constants/plugins.js +1 -1
- package/dist/src/redteam/constants/strategies.d.ts +1 -1
- package/dist/src/redteam/constants/strategies.js +1 -0
- package/dist/src/redteam/plugins/vlguard.d.ts +53 -4
- package/dist/src/redteam/plugins/vlguard.js +362 -46
- package/dist/src/redteam/providers/constants.d.ts +2 -2
- package/dist/src/redteam/providers/constants.js +2 -2
- package/dist/src/redteam/providers/crescendo/index.d.ts +1 -1
- package/dist/src/redteam/providers/crescendo/index.js +5 -3
- package/dist/src/redteam/providers/hydra/index.js +1 -1
- package/dist/src/server/routes/modelAudit.js +4 -4
- package/dist/src/share.js +4 -2
- package/dist/src/telemetry.js +44 -8
- package/dist/src/types/env.d.ts +3 -0
- package/dist/src/types/env.js +1 -0
- package/dist/src/types/index.d.ts +896 -615
- package/dist/src/types/index.js +1 -0
- package/dist/src/types/providers.d.ts +1 -0
- package/dist/src/types/tracing.d.ts +3 -0
- package/dist/src/util/database.d.ts +6 -4
- package/dist/src/util/file.js +6 -4
- package/dist/src/util/modelAuditCliParser.d.ts +4 -4
- package/dist/src/util/xlsx.js +52 -26
- package/dist/src/validators/providers.d.ts +142 -122
- package/dist/src/validators/providers.js +4 -6
- package/dist/src/validators/redteam.d.ts +36 -28
- package/dist/src/validators/redteam.js +9 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +28 -26
- package/dist/drizzle/CLAUDE.md +0 -65
- package/dist/src/app/assets/index-DifT6VGT.js +0 -51
- package/dist/src/app/assets/sync-Oo-W_Rbj.js +0 -1
- package/dist/src/app/assets/vendor-mui-x-C2xF-yiO.js +0 -45
- package/dist/src/providers/groq.js +0 -48
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.XAIResponsesProvider = void 0;
|
|
7
|
+
exports.createXAIResponsesProvider = createXAIResponsesProvider;
|
|
8
|
+
const cache_1 = require("../../cache");
|
|
9
|
+
const envars_1 = require("../../envars");
|
|
10
|
+
const logger_1 = __importDefault(require("../../logger"));
|
|
11
|
+
const index_1 = require("../../util/index");
|
|
12
|
+
const file_1 = require("../../util/file");
|
|
13
|
+
const functionCallbackUtils_1 = require("../functionCallbackUtils");
|
|
14
|
+
const shared_1 = require("../shared");
|
|
15
|
+
const index_2 = require("../responses/index");
|
|
16
|
+
const chat_1 = require("./chat");
|
|
17
|
+
/**
|
|
18
|
+
* xAI Responses API Provider
|
|
19
|
+
*
|
|
20
|
+
* Supports xAI's Responses API with Agent Tools for autonomous agent workflows.
|
|
21
|
+
* This enables Grok models to autonomously search the web, X, execute code,
|
|
22
|
+
* and interact with MCP servers.
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* xai:responses:grok-4-1-fast-reasoning
|
|
26
|
+
* xai:responses:grok-4-fast
|
|
27
|
+
* xai:responses:grok-4
|
|
28
|
+
*/
|
|
29
|
+
class XAIResponsesProvider {
|
|
30
|
+
constructor(modelName, options = {}) {
|
|
31
|
+
this.functionCallbackHandler = new functionCallbackUtils_1.FunctionCallbackHandler();
|
|
32
|
+
this.modelName = modelName;
|
|
33
|
+
this.config = options.config || {};
|
|
34
|
+
this.env = options.env;
|
|
35
|
+
// Initialize the shared response processor
|
|
36
|
+
this.processor = new index_2.ResponsesProcessor({
|
|
37
|
+
modelName: this.modelName,
|
|
38
|
+
providerType: 'xai',
|
|
39
|
+
functionCallbackHandler: this.functionCallbackHandler,
|
|
40
|
+
costCalculator: (modelName, usage, config) => (0, chat_1.calculateXAICost)(modelName, config || {}, usage?.input_tokens || usage?.prompt_tokens, usage?.output_tokens || usage?.completion_tokens) ?? 0,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
id() {
|
|
44
|
+
return `xai:responses:${this.modelName}`;
|
|
45
|
+
}
|
|
46
|
+
toString() {
|
|
47
|
+
return `[xAI Responses Provider ${this.modelName}]`;
|
|
48
|
+
}
|
|
49
|
+
toJSON() {
|
|
50
|
+
return {
|
|
51
|
+
provider: 'xai:responses',
|
|
52
|
+
model: this.modelName,
|
|
53
|
+
config: {
|
|
54
|
+
...this.config,
|
|
55
|
+
apiKey: undefined, // Don't expose API key
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
getApiKey() {
|
|
60
|
+
return this.config.apiKey || (0, envars_1.getEnvString)('XAI_API_KEY');
|
|
61
|
+
}
|
|
62
|
+
getApiUrl() {
|
|
63
|
+
if (this.config.apiBaseUrl) {
|
|
64
|
+
return this.config.apiBaseUrl;
|
|
65
|
+
}
|
|
66
|
+
if (this.config.region) {
|
|
67
|
+
return `https://${this.config.region}.api.x.ai/v1`;
|
|
68
|
+
}
|
|
69
|
+
return 'https://api.x.ai/v1';
|
|
70
|
+
}
|
|
71
|
+
async getRequestBody(prompt, context, _callApiOptions) {
|
|
72
|
+
const config = {
|
|
73
|
+
...this.config,
|
|
74
|
+
...context?.prompt?.config,
|
|
75
|
+
};
|
|
76
|
+
// Parse input - can be string or array of messages
|
|
77
|
+
let input;
|
|
78
|
+
try {
|
|
79
|
+
const parsedJson = JSON.parse(prompt);
|
|
80
|
+
if (Array.isArray(parsedJson)) {
|
|
81
|
+
input = parsedJson;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
input = prompt;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
input = prompt;
|
|
89
|
+
}
|
|
90
|
+
// Handle max_output_tokens
|
|
91
|
+
const maxOutputTokens = config.max_output_tokens ?? 4096;
|
|
92
|
+
// Handle temperature
|
|
93
|
+
const temperature = config.temperature ?? 0.7;
|
|
94
|
+
// Load response_format from external file if needed
|
|
95
|
+
const responseFormat = config.response_format
|
|
96
|
+
? (0, file_1.maybeLoadFromExternalFile)((0, index_1.renderVarsInObject)(config.response_format, context?.vars))
|
|
97
|
+
: undefined;
|
|
98
|
+
// Build text format configuration
|
|
99
|
+
let textFormat;
|
|
100
|
+
if (responseFormat) {
|
|
101
|
+
if (responseFormat.type === 'json_object') {
|
|
102
|
+
textFormat = { format: { type: 'json_object' } };
|
|
103
|
+
}
|
|
104
|
+
else if (responseFormat.type === 'json_schema') {
|
|
105
|
+
const schema = (0, file_1.maybeLoadFromExternalFile)((0, index_1.renderVarsInObject)(responseFormat.schema || responseFormat.json_schema?.schema, context?.vars));
|
|
106
|
+
const schemaName = responseFormat.json_schema?.name || responseFormat.name || 'response_schema';
|
|
107
|
+
textFormat = {
|
|
108
|
+
format: {
|
|
109
|
+
type: 'json_schema',
|
|
110
|
+
name: schemaName,
|
|
111
|
+
schema,
|
|
112
|
+
strict: true,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
textFormat = { format: { type: 'text' } };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Load tools from external file if needed
|
|
121
|
+
const loadedTools = config.tools
|
|
122
|
+
? await (0, index_1.maybeLoadToolsFromExternalFile)(config.tools, context?.vars)
|
|
123
|
+
: undefined;
|
|
124
|
+
// Build request body
|
|
125
|
+
const body = {
|
|
126
|
+
model: this.modelName,
|
|
127
|
+
input,
|
|
128
|
+
...(maxOutputTokens ? { max_output_tokens: maxOutputTokens } : {}),
|
|
129
|
+
...(temperature !== undefined ? { temperature } : {}),
|
|
130
|
+
...(config.instructions ? { instructions: config.instructions } : {}),
|
|
131
|
+
...(config.top_p !== undefined ? { top_p: config.top_p } : {}),
|
|
132
|
+
...(loadedTools && loadedTools.length > 0 ? { tools: loadedTools } : {}),
|
|
133
|
+
...(config.tool_choice ? { tool_choice: config.tool_choice } : {}),
|
|
134
|
+
...(config.previous_response_id ? { previous_response_id: config.previous_response_id } : {}),
|
|
135
|
+
...(textFormat ? { text: textFormat } : {}),
|
|
136
|
+
...('parallel_tool_calls' in config
|
|
137
|
+
? { parallel_tool_calls: Boolean(config.parallel_tool_calls) }
|
|
138
|
+
: {}),
|
|
139
|
+
...('store' in config ? { store: Boolean(config.store) } : {}),
|
|
140
|
+
...(config.user ? { user: config.user } : {}),
|
|
141
|
+
...(config.passthrough || {}),
|
|
142
|
+
};
|
|
143
|
+
// Filter unsupported parameters for Grok-4 models
|
|
144
|
+
if (chat_1.GROK_4_MODELS.includes(this.modelName)) {
|
|
145
|
+
delete body.presence_penalty;
|
|
146
|
+
delete body.frequency_penalty;
|
|
147
|
+
delete body.stop;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
body,
|
|
151
|
+
config: {
|
|
152
|
+
...config,
|
|
153
|
+
tools: loadedTools,
|
|
154
|
+
response_format: responseFormat,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async callApi(prompt, context, callApiOptions) {
|
|
159
|
+
const apiKey = this.getApiKey();
|
|
160
|
+
if (!apiKey) {
|
|
161
|
+
return {
|
|
162
|
+
error: 'xAI API key is not set. Set the XAI_API_KEY environment variable or add `apiKey` to the provider config.',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const { body, config } = await this.getRequestBody(prompt, context, callApiOptions);
|
|
166
|
+
logger_1.default.debug(`[xAI Responses] Calling ${this.getApiUrl()}/responses`, {
|
|
167
|
+
model: this.modelName,
|
|
168
|
+
hasTools: !!body.tools?.length,
|
|
169
|
+
toolTypes: body.tools?.map((t) => t.type),
|
|
170
|
+
});
|
|
171
|
+
let data;
|
|
172
|
+
let cached = false;
|
|
173
|
+
let status;
|
|
174
|
+
let statusText;
|
|
175
|
+
try {
|
|
176
|
+
const response = await (0, cache_1.fetchWithCache)(`${this.getApiUrl()}/responses`, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
headers: {
|
|
179
|
+
'Content-Type': 'application/json',
|
|
180
|
+
Authorization: `Bearer ${apiKey}`,
|
|
181
|
+
...config.headers,
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify(body),
|
|
184
|
+
}, shared_1.REQUEST_TIMEOUT_MS, 'json', context?.bustCache ?? context?.debug, this.config.maxRetries);
|
|
185
|
+
data = response.data;
|
|
186
|
+
cached = response.cached;
|
|
187
|
+
status = response.status;
|
|
188
|
+
statusText = response.statusText;
|
|
189
|
+
if (status < 200 || status >= 300) {
|
|
190
|
+
const errorMessage = `xAI API error: ${status} ${statusText}\n${typeof data === 'string' ? data : JSON.stringify(data)}`;
|
|
191
|
+
// Check for specific error types
|
|
192
|
+
if (data?.error?.code === 'invalid_prompt') {
|
|
193
|
+
return {
|
|
194
|
+
output: errorMessage,
|
|
195
|
+
tokenUsage: this.getTokenUsage(data, cached),
|
|
196
|
+
isRefusal: true,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return { error: errorMessage };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
204
|
+
// Handle common xAI errors
|
|
205
|
+
if (errorMessage.includes('502') || errorMessage.includes('Bad Gateway')) {
|
|
206
|
+
return {
|
|
207
|
+
error: `xAI API error: 502 Bad Gateway - This often indicates an invalid API key.\n\nTip: Ensure your XAI_API_KEY environment variable is set correctly. You can get an API key from https://x.ai/`,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
error: `xAI API error: ${errorMessage}\n\nIf this persists, verify your API key at https://x.ai/`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if (data.error) {
|
|
215
|
+
return {
|
|
216
|
+
error: `xAI API error: ${typeof data.error === 'string' ? data.error : JSON.stringify(data.error)}`,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// Use shared processor for consistent response handling
|
|
220
|
+
return this.processor.processResponseOutput(data, config, cached);
|
|
221
|
+
}
|
|
222
|
+
getTokenUsage(data, cached) {
|
|
223
|
+
if (!data.usage) {
|
|
224
|
+
return {};
|
|
225
|
+
}
|
|
226
|
+
if (cached) {
|
|
227
|
+
const totalTokens = data.usage.total_tokens || (data.usage.input_tokens || 0) + (data.usage.output_tokens || 0);
|
|
228
|
+
return { cached: totalTokens, total: totalTokens };
|
|
229
|
+
}
|
|
230
|
+
const promptTokens = data.usage.prompt_tokens || data.usage.input_tokens || 0;
|
|
231
|
+
const completionTokens = data.usage.completion_tokens || data.usage.output_tokens || 0;
|
|
232
|
+
const totalTokens = data.usage.total_tokens || promptTokens + completionTokens;
|
|
233
|
+
return {
|
|
234
|
+
total: totalTokens,
|
|
235
|
+
prompt: promptTokens,
|
|
236
|
+
completion: completionTokens,
|
|
237
|
+
...(data.usage.completion_tokens_details
|
|
238
|
+
? {
|
|
239
|
+
completionDetails: {
|
|
240
|
+
reasoning: data.usage.completion_tokens_details.reasoning_tokens,
|
|
241
|
+
},
|
|
242
|
+
}
|
|
243
|
+
: {}),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.XAIResponsesProvider = XAIResponsesProvider;
|
|
248
|
+
/**
|
|
249
|
+
* Create an xAI Responses provider
|
|
250
|
+
*
|
|
251
|
+
* @param providerPath - Provider path in format xai:responses:<model>
|
|
252
|
+
* @param options - Provider options
|
|
253
|
+
* @returns XAIResponsesProvider instance
|
|
254
|
+
*/
|
|
255
|
+
function createXAIResponsesProvider(providerPath, options = {}) {
|
|
256
|
+
// Parse model name from path: xai:responses:<model>
|
|
257
|
+
const parts = providerPath.split(':');
|
|
258
|
+
const modelName = parts.slice(2).join(':');
|
|
259
|
+
if (!modelName) {
|
|
260
|
+
throw new Error('Model name is required for xAI Responses provider. Use format: xai:responses:<model>');
|
|
261
|
+
}
|
|
262
|
+
return new XAIResponsesProvider(modelName, {
|
|
263
|
+
config: options.config,
|
|
264
|
+
id: options.id,
|
|
265
|
+
env: options.env,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=responses.js.map
|
|
@@ -3,7 +3,7 @@ export declare const REDTEAM_DEFAULTS: {
|
|
|
3
3
|
readonly MAX_CONCURRENCY: 4;
|
|
4
4
|
readonly NUM_TESTS: 10;
|
|
5
5
|
};
|
|
6
|
-
export declare const REDTEAM_MODEL = "openai:chat:gpt-
|
|
6
|
+
export declare const REDTEAM_MODEL = "openai:chat:gpt-5-2025-08-07";
|
|
7
7
|
export declare const LLAMA_GUARD_REPLICATE_PROVIDER = "replicate:moderation:meta/llama-guard-4-12b";
|
|
8
8
|
export declare const LLAMA_GUARD_ENABLED_CATEGORIES: string[];
|
|
9
9
|
export declare const FOUNDATION_PLUGINS: readonly ["ascii-smuggling", "beavertails", "bias:age", "bias:disability", "bias:gender", "bias:race", "contracts", "cyberseceval", "donotanswer", "divergent-repetition", "excessive-agency", "hallucination", "harmful:chemical-biological-weapons", "harmful:child-exploitation", "harmful:copyright-violations", "harmful:cybercrime", "harmful:cybercrime:malicious-code", "harmful:graphic-content", "harmful:harassment-bullying", "harmful:hate", "harmful:illegal-activities", "harmful:illegal-drugs", "harmful:illegal-drugs:meth", "harmful:indiscriminate-weapons", "harmful:insults", "harmful:intellectual-property", "harmful:misinformation-disinformation", "harmful:non-violent-crime", "harmful:profanity", "harmful:radicalization", "harmful:self-harm", "harmful:sex-crime", "harmful:sexual-content", "harmful:specialized-advice", "harmful:unsafe-practices", "harmful:violent-crime", "harmful:weapons:ied", "hijacking", "imitation", "overreliance", "pii:direct", "pliny", "politics", "religion"];
|
|
@@ -7,7 +7,7 @@ exports.REDTEAM_DEFAULTS = {
|
|
|
7
7
|
MAX_CONCURRENCY: 4,
|
|
8
8
|
NUM_TESTS: 10,
|
|
9
9
|
};
|
|
10
|
-
exports.REDTEAM_MODEL = 'openai:chat:gpt-
|
|
10
|
+
exports.REDTEAM_MODEL = 'openai:chat:gpt-5-2025-08-07';
|
|
11
11
|
// LlamaGuard 4 is the default on Replicate (supports S14: Code Interpreter Abuse)
|
|
12
12
|
exports.LLAMA_GUARD_REPLICATE_PROVIDER = 'replicate:moderation:meta/llama-guard-4-12b';
|
|
13
13
|
// For LlamaGuard 3 compatibility:
|
|
@@ -12,7 +12,7 @@ export declare const MULTI_MODAL_STRATEGIES: readonly ["audio", "image", "video"
|
|
|
12
12
|
export type MultiModalStrategy = (typeof MULTI_MODAL_STRATEGIES)[number];
|
|
13
13
|
export declare const AGENTIC_STRATEGIES: readonly ["crescendo", "goat", "custom", "jailbreak", "jailbreak:hydra", "jailbreak:meta", "jailbreak:tree", "mischievous-user", "simba"];
|
|
14
14
|
export type AgenticStrategy = (typeof AGENTIC_STRATEGIES)[number];
|
|
15
|
-
export declare const DATASET_PLUGINS: readonly ["beavertails", "cyberseceval", "donotanswer", "harmbench", "toxic-chat", "aegis", "pliny", "unsafebench", "xstest"];
|
|
15
|
+
export declare const DATASET_PLUGINS: readonly ["beavertails", "cyberseceval", "donotanswer", "harmbench", "toxic-chat", "aegis", "pliny", "unsafebench", "vlguard", "xstest"];
|
|
16
16
|
export type DatasetPlugin = (typeof DATASET_PLUGINS)[number];
|
|
17
17
|
export declare const ADDITIONAL_STRATEGIES: readonly ["audio", "authoritative-markup-injection", "base64", "best-of-n", "camelcase", "citation", "crescendo", "custom", "emoji", "gcg", "goat", "hex", "homoglyph", "image", "jailbreak:hydra", "jailbreak", "jailbreak:likert", "jailbreak:meta", "jailbreak:tree", "layer", "leetspeak", "math-prompt", "mischievous-user", "morse", "multilingual", "piglatin", "prompt-injection", "retry", "rot13", "simba", "video"];
|
|
18
18
|
export type AdditionalStrategy = (typeof ADDITIONAL_STRATEGIES)[number];
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { ImageDatasetGraderBase, ImageDatasetPluginBase, type ImageDatasetPluginConfig } from './imageDatasetPluginBase';
|
|
2
2
|
import { ImageDatasetManager } from './imageDatasetUtils';
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
declare const SPLIT_INFO: {
|
|
4
|
+
readonly test: {
|
|
5
|
+
readonly totalRecords: 1000;
|
|
6
|
+
};
|
|
7
|
+
readonly train: {
|
|
8
|
+
readonly totalRecords: 1999;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export type VLGuardSplit = keyof typeof SPLIT_INFO | 'both';
|
|
12
|
+
export declare const VALID_CATEGORIES: readonly ["Privacy", "Risky Behavior", "Deception", "Hateful Speech", "privacy", "risky behavior", "deception", "discrimination"];
|
|
13
|
+
export declare const VALID_SUBCATEGORIES: readonly ["Personal data", "Professional advice", "Political", "Sexually explicit", "Violence", "Disinformation", "Discrimination by sex", "Discrimination by race", "personal data", "professional advice", "political", "sexually explicit", "violence", "disinformation", "sex", "other"];
|
|
5
14
|
export type VLGuardCategory = (typeof VALID_CATEGORIES)[number];
|
|
6
15
|
export type VLGuardSubcategory = (typeof VALID_SUBCATEGORIES)[number];
|
|
7
16
|
interface VLGuardInput {
|
|
@@ -9,13 +18,18 @@ interface VLGuardInput {
|
|
|
9
18
|
category: string;
|
|
10
19
|
subcategory: string;
|
|
11
20
|
question: string;
|
|
21
|
+
safe: boolean;
|
|
12
22
|
}
|
|
13
23
|
interface VLGuardPluginConfig extends ImageDatasetPluginConfig {
|
|
14
24
|
categories?: VLGuardCategory[];
|
|
15
25
|
subcategories?: VLGuardSubcategory[];
|
|
26
|
+
includeUnsafe?: boolean;
|
|
27
|
+
includeSafe?: boolean;
|
|
28
|
+
split?: VLGuardSplit;
|
|
16
29
|
}
|
|
17
30
|
/**
|
|
18
31
|
* DatasetManager to handle VLGuard dataset caching and filtering
|
|
32
|
+
* Fetches metadata from {split}.json and images from HuggingFace
|
|
19
33
|
* @internal - exported for testing purposes only
|
|
20
34
|
*/
|
|
21
35
|
export declare class VLGuardDatasetManager extends ImageDatasetManager<VLGuardInput> {
|
|
@@ -23,19 +37,54 @@ export declare class VLGuardDatasetManager extends ImageDatasetManager<VLGuardIn
|
|
|
23
37
|
protected pluginId: string;
|
|
24
38
|
protected datasetPath: string;
|
|
25
39
|
protected fetchLimit: number;
|
|
40
|
+
private metadataCache;
|
|
41
|
+
private splitCache;
|
|
42
|
+
private currentSplit;
|
|
26
43
|
private constructor();
|
|
27
44
|
/**
|
|
28
45
|
* Get singleton instance
|
|
29
46
|
*/
|
|
30
47
|
static getInstance(): VLGuardDatasetManager;
|
|
48
|
+
/**
|
|
49
|
+
* Set the split to use for fetching records
|
|
50
|
+
*/
|
|
51
|
+
setSplit(split: VLGuardSplit): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get the current split
|
|
54
|
+
*/
|
|
55
|
+
getSplit(): VLGuardSplit;
|
|
31
56
|
/**
|
|
32
57
|
* Clear the cache - useful for testing
|
|
33
58
|
*/
|
|
34
59
|
static clearCache(): void;
|
|
35
60
|
/**
|
|
36
|
-
*
|
|
61
|
+
* Required by base class but not used since we override ensureDatasetLoaded
|
|
62
|
+
*/
|
|
63
|
+
protected processRecords(_records: any[]): Promise<VLGuardInput[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch metadata from a specific split's JSON file
|
|
66
|
+
*/
|
|
67
|
+
private fetchMetadataForSplit;
|
|
68
|
+
/**
|
|
69
|
+
* Process a single metadata record with its corresponding image URL
|
|
70
|
+
*/
|
|
71
|
+
private processSingleRecord;
|
|
72
|
+
/**
|
|
73
|
+
* Fetch image URLs from the datasets-server API for a specific split (handles pagination)
|
|
74
|
+
*/
|
|
75
|
+
private fetchImageUrlsForSplit;
|
|
76
|
+
/**
|
|
77
|
+
* Process metadata records with URLs and bounded concurrency to avoid OOM
|
|
78
|
+
*/
|
|
79
|
+
private processMetadataRecordsWithUrls;
|
|
80
|
+
/**
|
|
81
|
+
* Load data for a single split and return indexed records with their image map
|
|
82
|
+
*/
|
|
83
|
+
private loadSplitData;
|
|
84
|
+
/**
|
|
85
|
+
* Override ensureDatasetLoaded to use our custom metadata fetching
|
|
37
86
|
*/
|
|
38
|
-
protected
|
|
87
|
+
protected ensureDatasetLoaded(): Promise<void>;
|
|
39
88
|
/**
|
|
40
89
|
* Get records filtered by category, fetching dataset if needed
|
|
41
90
|
*/
|