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.
Files changed (131) hide show
  1. package/dist/package.json +28 -26
  2. package/dist/src/app/assets/index-eJ2lMe94.js +51 -0
  3. package/dist/src/app/assets/{source-map-support-Bnh0UQ2S.js → source-map-support-1v4oeb7P.js} +1 -1
  4. package/dist/src/app/assets/sync-CtLQRuC1.js +1 -0
  5. package/dist/src/app/assets/{vendor-charts-T60Uk0Z3.js → vendor-charts-DnVv66VV.js} +1 -1
  6. package/dist/src/app/assets/{vendor-markdown-DLig-KJh.js → vendor-markdown-DCpQIyMA.js} +1 -1
  7. package/dist/src/app/assets/{vendor-mui-core-5BLaiG3c.js → vendor-mui-core-Boqnpf9f.js} +1 -1
  8. package/dist/src/app/assets/{vendor-mui-icons-fn39Fu2e.js → vendor-mui-icons-B8MqoVbj.js} +1 -1
  9. package/dist/src/app/assets/vendor-mui-x-CGSS6QHF.js +45 -0
  10. package/dist/src/app/assets/{vendor-utils-DYBMEuwX.js → vendor-utils-DdfHIEy8.js} +1 -1
  11. package/dist/src/app/index.html +7 -7
  12. package/dist/src/assertions/guardrails.d.ts +1 -1
  13. package/dist/src/assertions/guardrails.js +18 -9
  14. package/dist/src/assertions/index.d.ts +1 -1
  15. package/dist/src/assertions/index.js +9 -3
  16. package/dist/src/assertions/searchRubric.d.ts +3 -0
  17. package/dist/src/assertions/searchRubric.js +18 -0
  18. package/dist/src/commands/eval.js +1 -1
  19. package/dist/src/commands/modelScan.d.ts +7 -1
  20. package/dist/src/commands/modelScan.js +121 -59
  21. package/dist/src/database/index.d.ts +6 -0
  22. package/dist/src/database/index.js +11 -0
  23. package/dist/src/database/tables.d.ts +46 -24
  24. package/dist/src/envars.d.ts +17 -0
  25. package/dist/src/generated/constants.js +1 -1
  26. package/dist/src/logger.d.ts +5 -0
  27. package/dist/src/logger.js +28 -0
  28. package/dist/src/main.js +17 -6
  29. package/dist/src/matchers.d.ts +1 -0
  30. package/dist/src/matchers.js +80 -0
  31. package/dist/src/models/eval.d.ts +2 -1
  32. package/dist/src/models/eval.js +44 -2
  33. package/dist/src/prompts/grading.d.ts +1 -0
  34. package/dist/src/prompts/grading.js +26 -1
  35. package/dist/src/prompts/index.d.ts +1 -0
  36. package/dist/src/prompts/index.js +4 -1
  37. package/dist/src/providers/adaline.gateway.js +2 -2
  38. package/dist/src/providers/anthropic/defaults.d.ts +1 -1
  39. package/dist/src/providers/anthropic/defaults.js +15 -0
  40. package/dist/src/providers/azure/chat.d.ts +3 -1
  41. package/dist/src/providers/azure/chat.js +16 -3
  42. package/dist/src/providers/azure/defaults.js +660 -141
  43. package/dist/src/providers/azure/responses.d.ts +5 -0
  44. package/dist/src/providers/azure/responses.js +33 -4
  45. package/dist/src/providers/azure/types.d.ts +4 -0
  46. package/dist/src/providers/bedrock/agents.d.ts +1 -1
  47. package/dist/src/providers/bedrock/agents.js +2 -2
  48. package/dist/src/providers/bedrock/base.d.ts +40 -0
  49. package/dist/src/providers/bedrock/base.js +171 -0
  50. package/dist/src/providers/bedrock/converse.d.ts +146 -0
  51. package/dist/src/providers/bedrock/converse.js +1044 -0
  52. package/dist/src/providers/bedrock/index.d.ts +1 -34
  53. package/dist/src/providers/bedrock/index.js +4 -159
  54. package/dist/src/providers/bedrock/knowledgeBase.d.ts +1 -1
  55. package/dist/src/providers/bedrock/knowledgeBase.js +2 -2
  56. package/dist/src/providers/bedrock/nova-sonic.d.ts +2 -1
  57. package/dist/src/providers/bedrock/nova-sonic.js +2 -2
  58. package/dist/src/providers/claude-agent-sdk.d.ts +58 -1
  59. package/dist/src/providers/claude-agent-sdk.js +22 -1
  60. package/dist/src/providers/defaults.js +4 -0
  61. package/dist/src/providers/github/defaults.js +6 -6
  62. package/dist/src/providers/google/types.d.ts +25 -0
  63. package/dist/src/providers/google/util.d.ts +2 -0
  64. package/dist/src/providers/google/vertex.js +78 -22
  65. package/dist/src/providers/{groq.d.ts → groq/chat.d.ts} +26 -20
  66. package/dist/src/providers/groq/chat.js +79 -0
  67. package/dist/src/providers/groq/index.d.ts +5 -0
  68. package/dist/src/providers/groq/index.js +24 -0
  69. package/dist/src/providers/groq/responses.d.ts +106 -0
  70. package/dist/src/providers/groq/responses.js +64 -0
  71. package/dist/src/providers/groq/types.d.ts +44 -0
  72. package/dist/src/providers/groq/types.js +3 -0
  73. package/dist/src/providers/groq/util.d.ts +15 -0
  74. package/dist/src/providers/groq/util.js +28 -0
  75. package/dist/src/providers/mcp/client.d.ts +8 -0
  76. package/dist/src/providers/mcp/client.js +60 -10
  77. package/dist/src/providers/mcp/types.d.ts +21 -0
  78. package/dist/src/providers/openai/chatkit-pool.d.ts +114 -0
  79. package/dist/src/providers/openai/chatkit-pool.js +548 -0
  80. package/dist/src/providers/openai/chatkit-types.d.ts +73 -0
  81. package/dist/src/providers/openai/chatkit-types.js +3 -0
  82. package/dist/src/providers/openai/chatkit.d.ts +76 -0
  83. package/dist/src/providers/openai/chatkit.js +879 -0
  84. package/dist/src/providers/openai/codex-sdk.d.ts +109 -0
  85. package/dist/src/providers/openai/codex-sdk.js +346 -0
  86. package/dist/src/providers/openai/defaults.d.ts +2 -0
  87. package/dist/src/providers/openai/defaults.js +10 -4
  88. package/dist/src/providers/registry.js +48 -9
  89. package/dist/src/providers/responses/types.d.ts +1 -1
  90. package/dist/src/providers/sagemaker.d.ts +2 -2
  91. package/dist/src/providers/webSearchUtils.d.ts +17 -0
  92. package/dist/src/providers/webSearchUtils.js +169 -0
  93. package/dist/src/providers/xai/chat.d.ts +61 -0
  94. package/dist/src/providers/xai/chat.js +68 -3
  95. package/dist/src/providers/xai/responses.d.ts +189 -0
  96. package/dist/src/providers/xai/responses.js +268 -0
  97. package/dist/src/redteam/constants/plugins.d.ts +1 -1
  98. package/dist/src/redteam/constants/plugins.js +1 -1
  99. package/dist/src/redteam/constants/strategies.d.ts +1 -1
  100. package/dist/src/redteam/constants/strategies.js +1 -0
  101. package/dist/src/redteam/plugins/vlguard.d.ts +53 -4
  102. package/dist/src/redteam/plugins/vlguard.js +362 -46
  103. package/dist/src/redteam/providers/constants.d.ts +2 -2
  104. package/dist/src/redteam/providers/constants.js +2 -2
  105. package/dist/src/redteam/providers/crescendo/index.d.ts +1 -1
  106. package/dist/src/redteam/providers/crescendo/index.js +5 -3
  107. package/dist/src/redteam/providers/hydra/index.js +1 -1
  108. package/dist/src/server/routes/modelAudit.js +4 -4
  109. package/dist/src/share.js +4 -2
  110. package/dist/src/telemetry.js +44 -8
  111. package/dist/src/types/env.d.ts +3 -0
  112. package/dist/src/types/env.js +1 -0
  113. package/dist/src/types/index.d.ts +896 -615
  114. package/dist/src/types/index.js +1 -0
  115. package/dist/src/types/providers.d.ts +1 -0
  116. package/dist/src/types/tracing.d.ts +3 -0
  117. package/dist/src/util/database.d.ts +6 -4
  118. package/dist/src/util/file.js +6 -4
  119. package/dist/src/util/modelAuditCliParser.d.ts +4 -4
  120. package/dist/src/util/xlsx.js +52 -26
  121. package/dist/src/validators/providers.d.ts +142 -122
  122. package/dist/src/validators/providers.js +4 -6
  123. package/dist/src/validators/redteam.d.ts +36 -28
  124. package/dist/src/validators/redteam.js +9 -3
  125. package/dist/tsconfig.tsbuildinfo +1 -1
  126. package/package.json +28 -26
  127. package/dist/drizzle/CLAUDE.md +0 -65
  128. package/dist/src/app/assets/index-DifT6VGT.js +0 -51
  129. package/dist/src/app/assets/sync-Oo-W_Rbj.js +0 -1
  130. package/dist/src/app/assets/vendor-mui-x-C2xF-yiO.js +0 -45
  131. 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-4.1-2025-04-14";
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-4.1-2025-04-14';
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];
@@ -57,6 +57,7 @@ exports.DATASET_PLUGINS = [
57
57
  'aegis',
58
58
  'pliny',
59
59
  'unsafebench',
60
+ 'vlguard',
60
61
  'xstest',
61
62
  ];
62
63
  exports.ADDITIONAL_STRATEGIES = [
@@ -1,7 +1,16 @@
1
1
  import { ImageDatasetGraderBase, ImageDatasetPluginBase, type ImageDatasetPluginConfig } from './imageDatasetPluginBase';
2
2
  import { ImageDatasetManager } from './imageDatasetUtils';
3
- export declare const VALID_CATEGORIES: readonly ["deception", "risky behavior", "privacy", "discrimination"];
4
- export declare const VALID_SUBCATEGORIES: readonly ["disinformation", "violence", "professional advice", "political", "sexually explicit", "personal data", "sex", "other"];
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
- * Process raw records from Hugging Face into VLGuardInput format
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 processRecords(records: any[]): Promise<VLGuardInput[]>;
87
+ protected ensureDatasetLoaded(): Promise<void>;
39
88
  /**
40
89
  * Get records filtered by category, fetching dataset if needed
41
90
  */