Repository: ollama
Issue: Structured generation cannot handle self referencing (recursion)
Labels: bug

### What is the issue?

Ollama structured genereation cannot handle self referencing recursion
```py
import json
from pydantic import BaseModel, Field
from typing import Optional

class Dossier(BaseModel):
    """Build a profile for the user"""
    name: str = Field(..., description="The name of the user")
    age: int = Field(..., description="The age of the user")
    friends: list["Dossier"] = []

print(json.dumps(Dossier.model_json_schema(), indent=2))

from ollama import chat

response = chat(
    messages=[
        {
            'role': 'user',
            'content': 'Hello my name is Tom I am 13 years old, my friend Bob is 14 years old'
        }
    ],
    model='llama3.1:8b-instruct-q2_K',
    format=Dossier.model_json_schema()
)
dossier = Dossier.model_validate_json(response.message.content)
print(dossier.model_dump_json(indent=2))
```
Output:
```
{
  "$defs": {
    "Dossier": {
      "description": "Build a profile for the user",
      "properties": {
        "name": {
          "description": "The name of the user",
          "title": "Name",
          "type": "string"
        },
        "age": {
          "description": "The age of the user",
          "title": "Age",
          "type": "integer"
        },
        "friends": {
          "default": [],
          "items": {
            "$ref": "#/$defs/Dossier"
          },
          "title": "Friends",
          "type": "array"
        }
      },
      "required": [
        "name",
        "age"
      ],
      "title": "Dossier",
      "type": "object"
    }
  },
  "$ref": "#/$defs/Dossier"
}
```
```
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
Cell In[54], [line 25](vscode-notebook-cell:?execution_count=54&line=25)
     [13](vscode-notebook-cell:?execution_count=54&line=13) from ollama import chat
     [15](vscode-notebook-cell:?execution_count=54&line=15) response = chat(
     [16](vscode-notebook-cell:?execution_count=54&line=16)     messages=[
     [17](vscode-notebook-cell:?execution_count=54&line=17)         {
   (...)
     [23](vscode-notebook-cell:?execution_count=54&line=23)     format=Dossier.model_json_schema()
     [24](vscode-notebook-cell:?execution_count=54&line=24) )
---> [25](vscode-notebook-cell:?execution_count=54&line=25) dossier = Dossier.model_validate_json(response.message.content)
     [26](vscode-notebook-cell:?execution_count=54&line=26) print(dossier.model_dump_json(indent=2))

File c:\Notes\ollama\.venv\lib\site-packages\pydantic\main.py:656, in BaseModel.model_validate_json(cls, json_data, strict, context)
    [654](file:///C:/Notes/ollama/.venv/lib/site-packages/pydantic/main.py:654) # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
    [655](file:///C:/Notes/ollama/.venv/lib/site-packages/pydantic/main.py:655) __tracebackhide__ = True
--> [656](file:///C:/Notes/ollama/.venv/lib/site-packages/pydantic/main.py:656) return cls.__pydantic_validator__.validate_json(json_data, strict=strict, context=context)

ValidationError: 1 validation error for Dossier
  Invalid JSON: expected value at line 1 column 1 [type=json_invalid, input_value="So you're 13 and your fr...m outside of class too?", input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/json_invalid
```

When destructured there is no problem
```py
import json
from pydantic import BaseModel, Field
from typing import Optional

class DossierInner(BaseModel):
    """Build a profile for the user"""
    name: str = Field(..., description="The name of the user")
    age: int = Field(..., description="The age of the user")

class Dossier(BaseModel):
    """Build a profile for the user"""
    name: str = Field(..., description="The name of the user")
    age: int = Field(..., description="The age of the user")
    friends: list[DossierInner] = []

print(json.dumps(Dossier.model_json_schema(), indent=2))

from ollama import chat

response = chat(
    messages=[
        {
            'role': 'user',
            'content': 'Hello my name is Tom I am 13 years old, my friend Bob is 14 years old'
        }
    ],
    model='llama3.1:8b-instruct-q2_K',
    format=Dossier.model_json_schema()
)
dossier = Dossier.model_validate_json(response.message.content)
print(dossier.model_dump_json(indent=2))
```
Output:
```
{
  "$defs": {
    "DossierInner": {
      "description": "Build a profile for the user",
      "properties": {
        "name": {
          "description": "The name of the user",
          "title": "Name",
          "type": "string"
        },
        "age": {
          "description": "The age of the user",
          "title": "Age",
          "type": "integer"
        }
      },
      "required": [
        "name",
        "age"
      ],
      "title": "DossierInner",
      "type": "object"
    }
  },
  "description": "Build a profile for the user",
  "properties": {
    "name": {
      "description": "The name of the user",
      "title": "Name",
      "type": "string"
    },
    "age": {
      "description": "The age of the user",
      "title": "Age",
      "type": "integer"
    },
    "friends": {
      "default": [],
      "items": {
        "$ref": "#/$defs/DossierInner"
      },
      "title": "Friends",
      "type": "array"
    }
  },
  "required": [
    "name",
    "age"
  ],
  "title": "Dossier",
  "type": "object"
}
{
  "name": "Tom",
  "age": -1,
  "friends": [
    {
      "name": "Bob",
      "age": -2
    }
  ]
}
```

### OS

Windows

### GPU

Nvidia

### CPU

AMD

### Ollama version

0.5.1