make this optionally support getting a list of all ollama models from the server, then add that ability to my ollama client c# unity script

import os
import sys
import uuid
import logging
from typing import Dict, List, Optional
from contextlib import asynccontextmanager

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from ollama import AsyncClient, ResponseError
import uvicorn

# Configure root logger for DEBUG output
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s %(name)s %(levelname)s %(message)s',
    stream=sys.stdout,
)

logger = logging.getLogger("uvicorn.error")

OLLAMA_API_URL = os.getenv("OLLAMA_API_URL", "http://localhost:11434")
DEFAULT_MODEL = "llama3.2"

# Max length of history messages per session
MAX_HISTORY_LENGTH = 30  # adjust as needed

app = FastAPI()

class Message(BaseModel):
    role: str
    content: str

class ChatRequest(BaseModel):
    model: Optional[str] = None
    message: str  # only the latest user message sent
    session_id: Optional[str] = None  # optional client-provided session id

# In-memory chat histories
chat_histories: Dict[str, List[Dict[str, str]]] = {}

# Global AsyncClient reused across requests after successful init
ollama_client: Optional[AsyncClient] = None

def trim_history(history: List[Dict[str, str]], max_length: int = MAX_HISTORY_LENGTH) -> List[Dict[str, str]]:
    """
    Trim history if it exceeds max_length.
    Keep the most recent messages but try to keep
    some assistant and user context.

    This simple implementation keeps the last max_length messages.
    """
    if len(history) <= max_length:
        return history

    # We're dropping the oldest messages beyond max_length limit
    trimmed = history[-max_length:]

    logger.debug(f"Trimmed chat history from {len(history)} to {len(trimmed)} messages")

    return trimmed

@asynccontextmanager
async def lifespan(app: FastAPI):
    global ollama_client
    ollama_client = AsyncClient(host=OLLAMA_API_URL)
    try:
        logger.debug(f"Attempting connection to Ollama API at {OLLAMA_API_URL} with model '{DEFAULT_MODEL}'")
        # Test connection with a simple prompt
        await ollama_client.chat(model=DEFAULT_MODEL, messages=[{"role": "user", "content": "ping"}], stream=False)
        logger.info(f"Connected to Ollama API at {OLLAMA_API_URL} with model '{DEFAULT_MODEL}' successfully")
    except Exception as e:
        logger.error(f"Failed to connect to Ollama API at {OLLAMA_API_URL} with model '{DEFAULT_MODEL}': {e}", exc_info=True)
        ollama_client = None
    yield
    # Optionally could add code here to close client or cleanup
    # but AsyncClient might not require explicit shutdown

app.router.lifespan_context = lifespan

@app.post("/chat")
async def chat_endpoint(request: ChatRequest):
    global ollama_client
    if ollama_client is None:
        logger.error("Ollama API client is not initialized")
        raise HTTPException(status_code=503, detail="Ollama API client unavailable")

    model = request.model or DEFAULT_MODEL

    # Obtain or create a session ID
    session_id = request.session_id or str(uuid.uuid4())
    if session_id not in chat_histories:
        chat_histories[session_id] = []

    # Append user's new message to the chat history
    chat_histories[session_id].append({"role": "user", "content": request.message})

    # Trim history to keep size manageable
    chat_histories[session_id] = trim_history(chat_histories[session_id], MAX_HISTORY_LENGTH)

    logger.debug(f"Session ID: {session_id}")
    logger.debug(f"Model: {model}")
    logger.debug(f"Current chat history ({len(chat_histories[session_id])} messages): {chat_histories[session_id]}")

    try:
        response = await ollama_client.chat(
            model=model,
            messages=chat_histories[session_id],
            stream=False,
        )

        assistant_message = response["message"]["content"]
        logger.debug(f"Assistant reply: {assistant_message}")

        # Append assistant reply to the chat history
        chat_histories[session_id].append({"role": "assistant", "content": assistant_message})

        # Trim again after assistant response
        chat_histories[session_id] = trim_history(chat_histories[session_id], MAX_HISTORY_LENGTH)

        return {
            "session_id": session_id,
            "reply": assistant_message,
        }

    except ResponseError as e:
        logger.error(f"Ollama ResponseError: {e.status_code} {e.content}")
        raise HTTPException(status_code=e.status_code, detail=e.content)

    except Exception as e:
        logger.error(f"Unexpected Ollama API error: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail="Internal server error")

if __name__ == "__main__":
    # Replace 'your_script_name' with your actual filename if different
    uvicorn.run("your_script_name:app", host="0.0.0.0", port=8784, log_level="debug", reload=True)

'main c# ollama client'
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class OllamaClient : MonoBehaviour
{
    [Tooltip("Base URL of the Ollama server")]
    public string baseUrl = "http://localhost:8784";

    [Tooltip("Model name to use, e.g. 'llama3.2'")]
    public string model = "llama3.2";

    public void Initialize(string url)
    {
        baseUrl = url.TrimEnd('/');
    }

    [Serializable]
    public class ChatRequest
    {
        public string model;
        public string message;
        public string session_id;  // optional

        public ChatRequest(string model, string message, string session_id = null)
        {
            this.model = model;
            this.message = message;
            this.session_id = session_id;
        }
    }

    /// <summary>
    /// Starts the coroutine to send a chat request.
    /// </summary>
    /// <param name="message">The latest user message to send</param>
    /// <param name="sessionId">Optional session ID to maintain conversation</param>
    /// <param name="onSuccess">Callback for successful response (string JSON)</param>
    /// <param name="onError">Callback on error</param>
    public void Chat(string message, string sessionId, Action<string> onSuccess, Action<string> onError)
    {
        StartCoroutine(ChatCoroutine(model, message, sessionId, onSuccess, onError));
    }

    private IEnumerator ChatCoroutine(string model, string message, string sessionId, Action<string> onSuccess, Action<string> onError)
    {
        ChatRequest requestData = new ChatRequest(model, message, sessionId);

        string json = JsonUtility.ToJson(requestData);

        byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(json);

        using (UnityWebRequest request = new UnityWebRequest(baseUrl + "/chat", "POST"))
        {
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");

            yield return request.SendWebRequest();

#if UNITY_2020_1_OR_NEWER
            if (request.result != UnityWebRequest.Result.Success)
#else
            if(request.isNetworkError || request.isHttpError)
#endif
            {
                onError?.Invoke($"Error: {request.error}\n{request.downloadHandler.text}");
            }
            else
            {
                onSuccess?.Invoke(request.downloadHandler.text);
            }
        }
    }
}

'my other ollama c# unity script'
using UnityEngine;

public class OllamaInfer : MonoBehaviour
{
    [Tooltip("Stores the plain text response from Ollama server.")]
    public string response;

    public TTSClientRunner runner;
    public FastAPIAudioTranscriber audioTranscriber;

    private string sessionId = null;  // To keep chat session continuity

    /// <summary>
    /// Sends a test message to the Ollama server.
    /// </summary>
    public void TestOllama()
    {
        var ollamaClient = gameObject.GetComponent<OllamaClient>();
        if (ollamaClient == null)
        {
            Debug.LogError("OllamaClient component not found on this GameObject.");
            return;
        }

        string testMessage = "test you seem broken rn?";

        ollamaClient.Chat(
            testMessage,
            sessionId,
            responseText =>
            {
                ProcessResponse(responseText, ollamaClient);
            },
            error => Debug.LogError(error)
        );
    }

    /// <summary>
    /// Sends a message to the Ollama chat model and gets a response.
    /// </summary>
    /// <param name="message">The user message to send</param>
    public void ChatBot(string message)
    {
        var ollamaClient = gameObject.GetComponent<OllamaClient>();
        if (ollamaClient == null)
        {
            Debug.LogError("OllamaClient component not found on this GameObject.");
            return;
        }

        ollamaClient.Chat(
            message,
            sessionId,
            responseText =>
            {
                ProcessResponse(responseText, ollamaClient);
            },
            error => Debug.LogError(error)
        );
    }


    /// <summary>
    /// Processes the JSON string response returned from the Ollama server.
    /// Updates session ID to maintain session.
    /// Triggers TTS and audio transcriber if available.
    /// </summary>
    /// <param name="responseText">Raw JSON response string</param>
    /// <param name="ollamaClient">Reference to the OllamaClient for session</param>
    private void ProcessResponse(string responseText, OllamaClient ollamaClient)
    {
        // The server response includes session_id and reply, e.g.:
        // { "session_id": "...", "reply": "Response text" }

        try
        {
            var jsonResponse = JsonUtility.FromJson<ChatResponse>(responseText);

            if (!string.IsNullOrEmpty(jsonResponse.reply))
            {
                response = jsonResponse.reply;
                runner.text = response;
                runner.RunTTSx();

                audioTranscriber.Reply = response;

                Debug.Log("Response: " + response);
            }
            else
            {
                Debug.LogWarning("Empty reply received.");
            }

            if (!string.IsNullOrEmpty(jsonResponse.session_id))
            {
                sessionId = jsonResponse.session_id;  // Save session ID to maintain context
            }
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"Error processing response JSON: {ex.Message}");
            // Fallback to raw response text
            response = responseText;
            runner.text = response;
            runner.RunTTSx();
            audioTranscriber.Reply = response;
            Debug.Log("Fallback Response: " + response);
        }
    }

    /// <summary>
    /// Model for parsing chat response JSON from server
    /// </summary>
    [System.Serializable]
    private class ChatResponse
    {
        public string session_id;
        public string reply;
    }
}

please provide all scripts in full fixed.