@@ -22,7 +22,7 @@ import (
2222 "strings"
2323
2424 "github.com/bytedance/sonic"
25- "github.com/getkin/kin-openapi/openapi3gen "
25+ "github.com/eino-contrib/jsonschema "
2626
2727 "github.com/cloudwego/eino/components/tool"
2828 "github.com/cloudwego/eino/internal/generic"
@@ -80,22 +80,68 @@ func goStruct2ToolInfo[T any](toolName, toolDesc string, opts ...Option) (*schem
8080 }, nil
8181}
8282
83- func goStruct2ParamsOneOf [T any ](opts ... Option ) (* schema.ParamsOneOf , error ) {
84- options := getToolOptions (opts ... )
85- schemaCustomizer := defaultSchemaCustomizer
86- if options .sc != nil {
87- schemaCustomizer = options .sc
88- }
83+ func goStruct2ParamsOneOf [T any ](_ ... Option ) (* schema.ParamsOneOf , error ) {
84+ s := jsonschema .Reflect (generic .NewInstance [T ]())
8985
90- sc , err := openapi3gen .NewSchemaRefForValue (generic .NewInstance [T ](), nil , openapi3gen .SchemaCustomizer (schemaCustomizer ))
91- if err != nil {
92- return nil , fmt .Errorf ("new SchemaRef from T failed: %w" , err )
86+ rootName := strings .TrimPrefix (s .Ref , "#/$defs/" )
87+ rootSchema := s .Definitions [rootName ]
88+ if rootSchema == nil {
89+ return nil , fmt .Errorf ("jsonschema '%s' not found" , rootName )
9390 }
9491
95- paramsOneOf := schema .NewParamsOneOfByOpenAPIV3 (sc .Value )
92+ rootSchema = resolveRef (rootSchema , s .Definitions )
93+ paramsOneOf := schema .NewParamsOneOfByJSONSchema (rootSchema )
9694
9795 return paramsOneOf , nil
96+ }
97+
98+ func resolveRef (s * jsonschema.Schema , defs jsonschema.Definitions ) * jsonschema.Schema {
99+ if s == nil {
100+ return nil
101+ }
102+
103+ if s .Ref != "" {
104+ if def , ok := defs [s .Ref [len ("#/$defs/" ):]]; ok {
105+ s .Ref = "" // Clear the ref after resolution
106+ return resolveRef (def , defs )
107+ }
108+ }
109+
110+ for i , s_ := range s .AllOf {
111+ s .AllOf [i ] = resolveRef (s_ , defs )
112+ }
113+ for i , s_ := range s .AnyOf {
114+ s .AnyOf [i ] = resolveRef (s_ , defs )
115+ }
116+ for i , s_ := range s .OneOf {
117+ s .OneOf [i ] = resolveRef (s_ , defs )
118+ }
119+ for i , s_ := range s .DependentSchemas {
120+ s .DependentSchemas [i ] = resolveRef (s_ , defs )
121+ }
122+ for i , s_ := range s .PrefixItems {
123+ s .PrefixItems [i ] = resolveRef (s_ , defs )
124+ }
125+ for i , s_ := range s .PatternProperties {
126+ s .PatternProperties [i ] = resolveRef (s_ , defs )
127+ }
128+ if s .Properties != nil {
129+ for pair := s .Properties .Oldest (); pair != nil ; pair = pair .Next () {
130+ s .Properties .Set (pair .Key , resolveRef (pair .Value , defs ))
131+ }
132+ }
98133
134+ s .Not = resolveRef (s .Not , defs )
135+ s .If = resolveRef (s .If , defs )
136+ s .Then = resolveRef (s .Then , defs )
137+ s .Else = resolveRef (s .Else , defs )
138+ s .Items = resolveRef (s .Items , defs )
139+ s .Contains = resolveRef (s .Contains , defs )
140+ s .AdditionalProperties = resolveRef (s .AdditionalProperties , defs )
141+ s .PropertyNames = resolveRef (s .PropertyNames , defs )
142+ s .ContentSchema = resolveRef (s .ContentSchema , defs )
143+
144+ return s
99145}
100146
101147// NewTool Create a tool, where the input and output are both in JSON format.
0 commit comments