-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve handling of JSON Schema in OpenAI API Response Context (#819)
* feat: add jsonschema.Validate and jsonschema.Unmarshal * fix Sanity check * remove slices.Contains * fix Sanity check * add SchemaWrapper * update api_integration_test.go * update method 'reflectSchema' to support 'omitempty' in JSON tag * add GenerateSchemaForType * update json_test.go * update `Warp` to `Wrap` * fix Sanity check * fix Sanity check * update api_internal_test.go * update README.md * update README.md * remove jsonschema.SchemaWrapper * remove jsonschema.SchemaWrapper * fix Sanity check * optimize code formatting
- Loading branch information
Showing
7 changed files
with
412 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package jsonschema | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
) | ||
|
||
func VerifySchemaAndUnmarshal(schema Definition, content []byte, v any) error { | ||
var data any | ||
err := json.Unmarshal(content, &data) | ||
if err != nil { | ||
return err | ||
} | ||
if !Validate(schema, data) { | ||
return errors.New("data validation failed against the provided schema") | ||
} | ||
return json.Unmarshal(content, &v) | ||
} | ||
|
||
func Validate(schema Definition, data any) bool { | ||
switch schema.Type { | ||
case Object: | ||
return validateObject(schema, data) | ||
case Array: | ||
return validateArray(schema, data) | ||
case String: | ||
_, ok := data.(string) | ||
return ok | ||
case Number: // float64 and int | ||
_, ok := data.(float64) | ||
if !ok { | ||
_, ok = data.(int) | ||
} | ||
return ok | ||
case Boolean: | ||
_, ok := data.(bool) | ||
return ok | ||
case Integer: | ||
_, ok := data.(int) | ||
return ok | ||
case Null: | ||
return data == nil | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
func validateObject(schema Definition, data any) bool { | ||
dataMap, ok := data.(map[string]any) | ||
if !ok { | ||
return false | ||
} | ||
for _, field := range schema.Required { | ||
if _, exists := dataMap[field]; !exists { | ||
return false | ||
} | ||
} | ||
for key, valueSchema := range schema.Properties { | ||
value, exists := dataMap[key] | ||
if exists && !Validate(valueSchema, value) { | ||
return false | ||
} else if !exists && contains(schema.Required, key) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
func validateArray(schema Definition, data any) bool { | ||
dataArray, ok := data.([]any) | ||
if !ok { | ||
return false | ||
} | ||
for _, item := range dataArray { | ||
if !Validate(*schema.Items, item) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
func contains[S ~[]E, E comparable](s S, v E) bool { | ||
for i := range s { | ||
if v == s[i] { | ||
return true | ||
} | ||
} | ||
return false | ||
} |
Oops, something went wrong.