Repository: ollama
Issue: Tool call support in Qwen 2.5 hallucinates with Maybe pattern
Labels: feature request

According to https://python.useinstructor.com/concepts/maybe/.

There is an issue with tool calling in a case like this:

```json
{
  "messages": [
    {
      "role": "system",
      "content": "Today's date is 2024-09-30. Please consider this when processing the availability information.\nIf you cannot extract the start date, use today.\nThis is the list of employees, with the initials, employee ID, full name, and skills:\n...\n\nDO NOT invent data. DO NOT hallucinate!"
    },
    {
      "role": "user",
      "content": "When does our colleague XYZ have two days available for a 2 days appointment?"
    }
  ],
  "model": "qwen2.5:7b-instruct-fp16",
  "tool_choice": {
    "type": "function",
    "function": {
      "name": "MaybeAvailabilityRequest"
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "MaybeAvailabilityRequest",
        "description": "Correctly extracted `MaybeAvailabilityRequest` with all the required parameters with correct types",
        "parameters": {
          "$defs": {
            "AvailabilityRequest": {
              "properties": {
                "personIds": {
                  "description": "List of person IDs to check availability for",
                  "items": {
                    "type": "integer"
                  },
                  "title": "Personids",
                  "type": "array"
                },
                "startDate": {
                  "description": "Start date for the availability check",
                  "title": "Startdate",
                  "type": "string"
                },
                "endDate": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "End date for the availability check",
                  "title": "Enddate"
                },
                "numberOfConsecutiveDays": {
                  "description": "Number of consecutive days required",
                  "title": "Numberofconsecutivedays",
                  "type": "integer"
                }
              },
              "required": [
                "personIds",
                "startDate",
                "endDate",
                "numberOfConsecutiveDays"
              ],
              "title": "AvailabilityRequest",
              "type": "object"
            }
          },
          "properties": {
            "result": {
              "anyOf": [
                {
                  "$ref": "#/$defs/AvailabilityRequest"
                },
                {
                  "type": "null"
                }
              ],
              "default": null
            },
            "error": {
              "default": false,
              "title": "Error",
              "type": "boolean"
            },
            "message": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "default": null,
              "title": "Message"
            }
          },
          "type": "object",
          "required": []
        }
      }
    }
  ]
}
```

it answers with this:
``` json
{
  "id": "chatcmpl-485",
  "object": "chat.completion",
  "created": 1727721983,
  "model": "qwen2.5:7b-instruct-fp16",
  "system_fingerprint": "fp_ollama",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_oe8h5as1",
            "type": "function",
            "function": {
              "name": "MaybeAvailabilityRequest",
              "arguments": "{\"error\":false,\"message\":null,\"result\":{\"availableDateRange\":[{\"end_date\":\"2024-10-03\",\"start_date\":\"2024-10-01\"}]}}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 477,
    "completion_tokens": 158,
    "total_tokens": 635
  }
}
```

Which is obviously wrong and not following the JSON schema from the tool call.

When I use non function calling and craft the prompt manually, it always gets the answer right.

.cc @JianxinMa

Thanks!