(t *Tool, h ToolHandlerFor[In, Out], cache *SchemaCache)
| 283 | } |
| 284 | |
| 285 | func toolForErr[In, Out any](t *Tool, h ToolHandlerFor[In, Out], cache *SchemaCache) (*Tool, ToolHandler, error) { |
| 286 | tt := *t |
| 287 | |
| 288 | // Special handling for an "any" input: treat as an empty object. |
| 289 | if reflect.TypeFor[In]() == reflect.TypeFor[any]() && t.InputSchema == nil { |
| 290 | tt.InputSchema = &jsonschema.Schema{Type: "object"} |
| 291 | } |
| 292 | |
| 293 | var inputResolved *jsonschema.Resolved |
| 294 | if _, err := setSchema[In](&tt.InputSchema, &inputResolved, cache); err != nil { |
| 295 | return nil, nil, fmt.Errorf("input schema: %w", err) |
| 296 | } |
| 297 | |
| 298 | // Handling for zero values: |
| 299 | // |
| 300 | // If Out is a pointer type and we've derived the output schema from its |
| 301 | // element type, use the zero value of its element type in place of a typed |
| 302 | // nil. |
| 303 | var ( |
| 304 | elemZero any // only non-nil if Out is a pointer type |
| 305 | outputResolved *jsonschema.Resolved |
| 306 | ) |
| 307 | if t.OutputSchema != nil || reflect.TypeFor[Out]() != reflect.TypeFor[any]() { |
| 308 | var err error |
| 309 | elemZero, err = setSchema[Out](&tt.OutputSchema, &outputResolved, cache) |
| 310 | if err != nil { |
| 311 | return nil, nil, fmt.Errorf("output schema: %v", err) |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | th := func(ctx context.Context, req *CallToolRequest) (*CallToolResult, error) { |
| 316 | var input json.RawMessage |
| 317 | if req.Params.Arguments != nil { |
| 318 | input = req.Params.Arguments |
| 319 | } |
| 320 | // Validate input and apply defaults. |
| 321 | var err error |
| 322 | input, err = applySchema(input, inputResolved) |
| 323 | if err != nil { |
| 324 | var errRes CallToolResult |
| 325 | errRes.SetError(fmt.Errorf("validating \"arguments\": %v", err)) |
| 326 | return &errRes, nil |
| 327 | } |
| 328 | |
| 329 | // Unmarshal and validate args. |
| 330 | var in In |
| 331 | if input != nil { |
| 332 | if err := internaljson.Unmarshal(input, &in); err != nil { |
| 333 | var errRes CallToolResult |
| 334 | errRes.SetError(err) |
| 335 | return &errRes, nil |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | // Call typed handler. |
| 340 | res, out, err := h(ctx, req, in) |
| 341 | // Handle server errors appropriately: |
| 342 | // - If the handler returns a structured error (like jsonrpc.Error), return it directly |
searching dependent graphs…