|
|
|
|
|
|
|
|
|
|
|
|
|
|
import type { AnalysisData } from "../api/GLTR_API"; |
|
|
import { |
|
|
validateTokenPredictions, |
|
|
validateTokenProbabilities, |
|
|
validateTokenConsistency |
|
|
} from './dataValidation'; |
|
|
import { tr } from '../lang/i18n-lite'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class DemoFormatError extends Error { |
|
|
constructor(message: string) { |
|
|
super(message); |
|
|
this.name = 'DemoFormatError'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function validateDemoFormat(data: any): data is AnalysisData { |
|
|
|
|
|
if (!data || typeof data !== 'object') { |
|
|
throw new DemoFormatError(tr('File content is not a valid JSON object')); |
|
|
} |
|
|
|
|
|
|
|
|
if (!data.request || typeof data.request !== 'object') { |
|
|
throw new DemoFormatError(tr('Missing required "request" field')); |
|
|
} |
|
|
|
|
|
if (typeof data.request.text !== 'string') { |
|
|
throw new DemoFormatError('request.text字段必须是字符串'); |
|
|
} |
|
|
|
|
|
|
|
|
if (!data.result || typeof data.result !== 'object') { |
|
|
throw new DemoFormatError(tr('Missing required "result" field')); |
|
|
} |
|
|
|
|
|
|
|
|
if (!Array.isArray(data.result.bpe_strings)) { |
|
|
throw new DemoFormatError('result.bpe_strings字段必须是数组'); |
|
|
} |
|
|
|
|
|
if (data.result.bpe_strings.length === 0) { |
|
|
throw new DemoFormatError('result.bpe_strings数组不能为空'); |
|
|
} |
|
|
|
|
|
|
|
|
for (let i = 0; i < data.result.bpe_strings.length; i++) { |
|
|
const token = data.result.bpe_strings[i]; |
|
|
if (!token || typeof token !== 'object') { |
|
|
throw new DemoFormatError(`result.bpe_strings[${i}]不是有效的对象`); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const predTopkError = validateTokenPredictions( |
|
|
data.result.bpe_strings as Array<{ pred_topk?: [string, number][] }> |
|
|
); |
|
|
if (predTopkError) { |
|
|
throw new DemoFormatError(predTopkError); |
|
|
} |
|
|
|
|
|
const probabilityError = validateTokenProbabilities( |
|
|
data.result.bpe_strings as Array<{ real_topk?: [number, number] }> |
|
|
); |
|
|
if (probabilityError) { |
|
|
throw new DemoFormatError(probabilityError); |
|
|
} |
|
|
|
|
|
|
|
|
const text = data.request.text; |
|
|
if (text) { |
|
|
const consistencyError = validateTokenConsistency( |
|
|
data.result.bpe_strings as Array<{ offset?: [number, number]; raw?: string }>, |
|
|
text, |
|
|
{ allowOverlap: true } |
|
|
); |
|
|
if (consistencyError) { |
|
|
throw new DemoFormatError(consistencyError); |
|
|
} |
|
|
} |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function isValidDemoFormat(data: unknown): data is AnalysisData { |
|
|
try { |
|
|
validateDemoFormat(data); |
|
|
return true; |
|
|
} catch { |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function ensureJsonExtension(filename: string): string { |
|
|
return filename.endsWith('.json') ? filename : `${filename}.json`; |
|
|
} |
|
|
|