Skip to content

Commit e67e54c

Browse files
ms-jpqstainless-app[bot]
authored andcommitted
fix: union definition re-using (#760)
1 parent 2104d8b commit e67e54c

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

lib/openai/helpers/structured_output/union_of.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,17 @@ def to_json_schema_inner(state:)
3636
mergeable_keys.each_key { mergeable_keys[_1] += 1 if schema.keys == _1 }
3737
end
3838
mergeable = mergeable_keys.any? { _1.last == schemas.length }
39-
mergeable ? OpenAI::Internal::Util.deep_merge(*schemas, concat: true) : {anyOf: schemas}
39+
if mergeable
40+
OpenAI::Internal::Util.deep_merge(*schemas, concat: true)
41+
else
42+
{
43+
anyOf: schemas.each do
44+
if _1.key?(:$ref)
45+
_1.update(OpenAI::Helpers::StructuredOutput::JsonSchemaConverter::NO_REF => true)
46+
end
47+
end
48+
}
49+
end
4050
end
4151
end
4252

test/openai/helpers/structured_output_test.rb

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class M3 < OpenAI::Helpers::StructuredOutput::BaseModel
3737

3838
U1 = OpenAI::Helpers::StructuredOutput::UnionOf[Integer, A1]
3939
U2 = OpenAI::Helpers::StructuredOutput::UnionOf[:type, m2: M2, m3: M3]
40+
U3 = OpenAI::Helpers::StructuredOutput::UnionOf[A1, A1]
4041

4142
def test_coerce
4243
cases = {
@@ -159,6 +160,12 @@ class M10 < OpenAI::Helpers::StructuredOutput::BaseModel
159160
required :b, -> { M9 }
160161
end
161162

163+
class M11 < OpenAI::Helpers::StructuredOutput::BaseModel
164+
required :a, U3
165+
required :b, A1
166+
required :c, A1
167+
end
168+
162169
def test_definition_reusing
163170
cases = {
164171
M6 => {
@@ -296,6 +303,27 @@ def test_definition_reusing
296303
}
297304
},
298305
:$ref => "#/$defs/"
306+
},
307+
U3 => {
308+
anyOf: [
309+
{type: "array", items: {type: "string"}},
310+
{type: "array", items: {type: "string"}}
311+
]
312+
},
313+
M11 => {
314+
type: "object",
315+
properties: {
316+
a: {
317+
anyOf: [
318+
{type: "array", items: {type: "string"}},
319+
{type: "array", items: {type: "string"}}
320+
]
321+
},
322+
b: {type: "array", items: {type: "string"}},
323+
c: {type: "array", items: {type: "string"}}
324+
},
325+
required: %w[a b c],
326+
additionalProperties: false
299327
}
300328
}
301329

@@ -307,23 +335,23 @@ def test_definition_reusing
307335
end
308336
end
309337

310-
class M11 < OpenAI::Helpers::StructuredOutput::BaseModel
338+
class M12 < OpenAI::Helpers::StructuredOutput::BaseModel
311339
required :a, OpenAI::Helpers::StructuredOutput::ParsedJson
312340
end
313341

314342
def test_parsed_json
315343
assert_pattern do
316-
M11.new(a: {dog: "woof"}) => {a: {dog: "woof"}}
344+
M12.new(a: {dog: "woof"}) => {a: {dog: "woof"}}
317345
end
318346

319347
err = JSON::ParserError.new("unexpected token at 'invalid json'")
320348

321-
m1 = M11.new(a: err)
349+
m1 = M12.new(a: err)
322350
assert_raises(OpenAI::Errors::ConversionError) do
323351
m1.a
324352
end
325353

326-
m2 = OpenAI::Internal::Type::Converter.coerce(M11, {a: err})
354+
m2 = OpenAI::Internal::Type::Converter.coerce(M12, {a: err})
327355
assert_raises(OpenAI::Errors::ConversionError) do
328356
m2.a
329357
end

0 commit comments

Comments
 (0)