Skip to content

Commit 398e1b3

Browse files
ssbushiinlined
authored andcommitted
feat: support model validation (#1868)
1 parent 5c7ba1f commit 398e1b3

File tree

3 files changed

+42
-34
lines changed

3 files changed

+42
-34
lines changed

genkit-tools/common/src/eval/evaluate.ts

+1-30
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,15 @@ import {
2626
EvalKeyAugments,
2727
EvalRun,
2828
EvalRunKey,
29-
GenerateRequest,
30-
GenerateRequestSchema,
3129
GenerateResponseSchema,
32-
MessageData,
3330
RunNewEvaluationRequest,
3431
SpanData,
3532
} from '../types';
3633
import {
3734
evaluatorName,
3835
generateTestCaseId,
3936
getEvalExtractors,
37+
getModelInput,
4038
hasAction,
4139
isEvaluator,
4240
logger,
@@ -440,30 +438,3 @@ function isSupportedActionRef(actionRef: string) {
440438
actionRef.startsWith(`/${supportedType}`)
441439
);
442440
}
443-
444-
function getModelInput(data: any, modelConfig: any): GenerateRequest {
445-
let message: MessageData;
446-
if (typeof data === 'string') {
447-
message = {
448-
role: 'user',
449-
content: [
450-
{
451-
text: data,
452-
},
453-
],
454-
} as MessageData;
455-
return {
456-
messages: message ? [message] : [],
457-
config: modelConfig,
458-
};
459-
} else {
460-
const maybeRequest = GenerateRequestSchema.safeParse(data);
461-
if (maybeRequest.success) {
462-
return maybeRequest.data;
463-
} else {
464-
throw new Error(
465-
`Unable to parse model input as MessageSchema as input. Details: ${maybeRequest.error}`
466-
);
467-
}
468-
}
469-
}

genkit-tools/common/src/eval/validate.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
ValidateDataRequest,
2626
ValidateDataResponse,
2727
} from '../types';
28+
import { getModelInput } from '../utils';
2829

2930
// Setup for AJV
3031
type JSONSchema = JSONSchemaType<any> | any;
@@ -61,8 +62,8 @@ export async function validateSchema(
6162
if (dataset.length === 0) {
6263
return { valid: true };
6364
}
64-
dataset.forEach((sample, index) => {
65-
const response = validate(targetSchema, sample.input);
65+
dataset.forEach((sample) => {
66+
const response = validate(actionRef, targetSchema, sample.input);
6667
if (!response.valid) {
6768
errorsMap[sample.testCaseId] = response.errors ?? [];
6869
}
@@ -74,7 +75,7 @@ export async function validateSchema(
7475
} else {
7576
const dataset = InferenceDatasetSchema.parse(data);
7677
dataset.forEach((sample, index) => {
77-
const response = validate(targetSchema, sample.input);
78+
const response = validate(actionRef, targetSchema, sample.input);
7879
if (!response.valid) {
7980
errorsMap[index.toString()] = response.errors ?? [];
8081
}
@@ -86,11 +87,16 @@ export async function validateSchema(
8687
}
8788

8889
function validate(
90+
actionRef: string,
8991
jsonSchema: JSONSchema,
9092
data: unknown
9193
): { valid: boolean; errors?: ErrorDetail[] } {
94+
const isModelAction = actionRef.startsWith('/model');
95+
let input = isModelAction
96+
? getModelInput(data, /* modelConfig= */ undefined)
97+
: data;
9298
const validator = ajv.compile(jsonSchema);
93-
const valid = validator(data) as boolean;
99+
const valid = validator(input) as boolean;
94100
const errors = validator.errors?.map((e) => e);
95101
return { valid, errors: errors?.map(toErrorDetail) };
96102
}

genkit-tools/common/src/utils/eval.ts

+31
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ import {
3737
EvaluationDatasetSchema,
3838
EvaluationSample,
3939
EvaluationSampleSchema,
40+
GenerateRequest,
41+
GenerateRequestSchema,
4042
InferenceDatasetSchema,
4143
InferenceSample,
4244
InferenceSampleSchema,
45+
MessageData,
4346
} from '../types';
4447
import { Action } from '../types/action';
4548
import { DocumentData, RetrieverResponse } from '../types/retrievers';
@@ -330,3 +333,31 @@ export async function hasAction(params: {
330333

331334
return actionsRecord.hasOwnProperty(actionRef);
332335
}
336+
337+
/** Helper function that maps string data to GenerateRequest */
338+
export function getModelInput(data: any, modelConfig: any): GenerateRequest {
339+
let message: MessageData;
340+
if (typeof data === 'string') {
341+
message = {
342+
role: 'user',
343+
content: [
344+
{
345+
text: data,
346+
},
347+
],
348+
} as MessageData;
349+
return {
350+
messages: message ? [message] : [],
351+
config: modelConfig,
352+
};
353+
} else {
354+
const maybeRequest = GenerateRequestSchema.safeParse(data);
355+
if (maybeRequest.success) {
356+
return maybeRequest.data;
357+
} else {
358+
throw new Error(
359+
`Unable to parse model input as MessageSchema as input. Details: ${maybeRequest.error}`
360+
);
361+
}
362+
}
363+
}

0 commit comments

Comments
 (0)