fix(confidence-engine): enforce openai strict object invariants

This commit is contained in:
2026-09-07 12:22:03 +01:00
parent e289f0be1f
commit 0d27d4935b
3 changed files with 31 additions and 2 deletions
+28
View File
@@ -190,6 +190,30 @@ describe("OllamaLlmProvider chat capability detection", () => {
});
describe("OpenAI reconstruction provider experiment seam", () => {
function assertStrictObjectInvariant(schema, root = schema, visited = new Set()) {
if (!schema || typeof schema !== "object" || visited.has(schema)) return;
visited.add(schema);
if (schema.properties) {
expect(schema.additionalProperties).toBe(false);
expect(new Set(schema.required)).toEqual(new Set(Object.keys(schema.properties)));
Object.values(schema.properties).forEach((property) =>
assertStrictObjectInvariant(property, root, visited),
);
}
if (schema.items) assertStrictObjectInvariant(schema.items, root, visited);
for (const branch of [
...(schema.anyOf ?? []),
...(schema.oneOf ?? []),
...(schema.allOf ?? []),
]) {
assertStrictObjectInvariant(branch, root, visited);
}
for (const definition of Object.values(schema.$defs ?? schema.definitions ?? {})) {
assertStrictObjectInvariant(definition, root, visited);
}
}
it("projects canonical optional fields as required but nullable", () => {
const nativeSchema = z.toJSONSchema(reconstructionV2Schema);
const projectedSchema = createOpenAIStrictSchema(
@@ -351,6 +375,10 @@ describe("OpenAI reconstruction provider experiment seam", () => {
relationships: [],
possibleFollowUpQuestions: [],
});
expect(new Set(schema.required)).toEqual(new Set(Object.keys(schema.properties)));
expect(schema.properties).toHaveProperty("relationships");
expect(schema.required).toContain("relationships");
assertStrictObjectInvariant(schema);
});
it("recursively projects arbitrary nested object schemas as strict", () => {