Added support for OpenAI-compatible structured output
This commit is contained in:
@@ -108,6 +108,30 @@ func parseJSON(body []byte) (any, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (v *StandardValidator) LoadSchemaDocument(ctx context.Context, schemaPath string) (any, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
resolved, err := v.resolveSchemaPath(schemaPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
raw, err := os.ReadFile(resolved)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read schema file %q: %w", resolved, err)
|
||||
}
|
||||
|
||||
var doc any
|
||||
if err := json.Unmarshal(raw, &doc); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode JSON schema %q: %w", resolved, err)
|
||||
}
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
func (v *StandardValidator) resolveSchemaPath(schemaPath string) (string, error) {
|
||||
if strings.TrimSpace(schemaPath) == "" {
|
||||
return "", errors.New("schema path is required for json_schema validation")
|
||||
|
||||
@@ -158,3 +158,52 @@ func TestStandardValidatorJSONSchemaSchemaLoadError(t *testing.T) {
|
||||
t.Fatal("expected schema load error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStandardValidatorLoadSchemaDocumentSuccess(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(tmp, "schema.json"), []byte(`{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"}
|
||||
}
|
||||
}`), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
v := NewStandardValidator(tmp)
|
||||
loader, ok := v.(SchemaDocumentLoader)
|
||||
if !ok {
|
||||
t.Fatal("standard validator must implement SchemaDocumentLoader")
|
||||
}
|
||||
|
||||
doc, err := loader.LoadSchemaDocument(context.Background(), "schema.json")
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error, got %v", err)
|
||||
}
|
||||
|
||||
obj, ok := doc.(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("expected object document, got %#v", doc)
|
||||
}
|
||||
if obj["type"] != "object" {
|
||||
t.Fatalf("expected schema type=object, got %#v", obj["type"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestStandardValidatorLoadSchemaDocumentInvalidJSON(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(tmp, "schema.json"), []byte(`{`), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
v := NewStandardValidator(tmp)
|
||||
loader, ok := v.(SchemaDocumentLoader)
|
||||
if !ok {
|
||||
t.Fatal("standard validator must implement SchemaDocumentLoader")
|
||||
}
|
||||
|
||||
_, err := loader.LoadSchemaDocument(context.Background(), "schema.json")
|
||||
if err == nil {
|
||||
t.Fatal("expected decode error")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,3 +9,8 @@ import (
|
||||
type Validator interface {
|
||||
Validate(ctx context.Context, artifact *domain.Artifact, contract domain.OutputContract) (domain.ValidationResult, error)
|
||||
}
|
||||
|
||||
// SchemaDocumentLoader loads JSON schema documents using validator path semantics.
|
||||
type SchemaDocumentLoader interface {
|
||||
LoadSchemaDocument(ctx context.Context, schemaPath string) (any, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user