reasoning: add proposal-level answer meaning guard
- Add answerMeaning schema with supportCategory and resolutionGuidance enums - Add pre-mutation guard that validates proposal alignment with answerMeaning - Update prompt builder to instruct the model on answerMeaning contract - Add tests for schema, guard logic, parsing defaults, and regression cases A-D
This commit is contained in:
@@ -144,6 +144,29 @@ const graphUpdateNodeChangeSchema = z.object({
|
||||
reason: z.string().min(1),
|
||||
});
|
||||
|
||||
export const answerSupportCategory = /** @type {const} */ ({
|
||||
relative_priority_only: "relative_priority_only",
|
||||
conditional_tradeoff: "conditional_tradeoff",
|
||||
uncertain: "uncertain",
|
||||
explicit_hard_constraint: "explicit_hard_constraint",
|
||||
other: "other",
|
||||
});
|
||||
|
||||
export const answerResolutionGuidance = /** @type {const} */ ({
|
||||
must_remain_unresolved: "must_remain_unresolved",
|
||||
may_resolve: "may_resolve",
|
||||
must_resolve: "must_resolve",
|
||||
});
|
||||
|
||||
export const answerMeaningSchema = z
|
||||
.object({
|
||||
userSupportedMeaning: z.string().min(1),
|
||||
possibleInference: z.string().nullable().optional(),
|
||||
supportCategory: z.enum(Object.values(answerSupportCategory)),
|
||||
resolutionGuidance: z.enum(Object.values(answerResolutionGuidance)),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const selectedQuestionSchema = z
|
||||
.object({
|
||||
nodeId: z.string().min(1),
|
||||
@@ -160,6 +183,7 @@ export const graphUpdateSchema = z.object({
|
||||
resolvedUnknownNodeIds: z.array(z.string()).default([]),
|
||||
affectedNodeIds: z.array(z.string()).default([]),
|
||||
selectedQuestion: selectedQuestionSchema.nullable().default(null),
|
||||
answerMeaning: answerMeaningSchema.nullable().default(null),
|
||||
});
|
||||
|
||||
/** @typedef {z.infer<typeof graphUpdateSchema>} GraphUpdate */
|
||||
|
||||
Reference in New Issue
Block a user