from openai import OpenAI
from openai.types.chat import ChatCompletion, ChatCompletionMessage
from typing import List
import json
client = OpenAI(api_key="abracadabra", base_url="http://localhost:8090")

def build_param(type, desc):
    return {"type": type, "description": desc}
def build_params(**kwargs):
    return kwargs
def build_function(name, desc, required, params):
    return {
        "type": "function",
        "function": {
            "name": name,
            "description": desc,
            "parameters": {
                "type": "object",
                "properties": params,
                "required": required
            }
        }
    }
def build_user_msg(text):
    return {
        "role": "user",
        "content": [{"type": "text", "text": text}]
    }
def get_weather_impl(city: str):
    return "晴天" # sunny

tools = [
    build_function(
        name="get_weather",
        desc="获取指定城市的天气。", # get weather for specified city.
        required=["city"],
        params=build_params(
            city=build_param(type="string", desc="指定城市，例如“北京”") # specify city. eg. "Beijing"
        )
    )
]
tool_map =  {"get_weather": get_weather_impl}

def add_create_resp(msgs: List, user_content):
    msgs.append(build_user_msg(user_content))
    while (True):
        resp: ChatCompletion = client.chat.completions.create(messages=msgs, model="Qwen3-VL-30B-A3B-Instruct", stream=False, tools=tools)
        resp_msg: ChatCompletionMessage = resp.choices[0].message
        msgs.append(resp_msg)
        if (resp_msg.tool_calls):
            for call in resp_msg.tool_calls:
                fname = call.function.name
                fargs = call.function.arguments
                if ("\\u" in fargs):
                    print("\\u found in args", fargs)
                fargs = json.loads(fargs)
                if (isinstance(fargs.get("city", None), str) and "\\u" in fargs["city"]):
                    print("\\u found in deserialized args", fargs)
                fret = tool_map[fname](**fargs)
                msgs.append({
                                 "role"        : "tool",
                                 "tool_call_id": call.id,
                                 "content"     : fret
                            })
            # continue multi-turn tool call?
        else:
            return resp_msg.content

msgs = []
add_create_resp(msgs, "北京的天气怎么样？")
add_create_resp(msgs, "上海的天气怎么样？")
add_create_resp(msgs, "大阪の天気はどう？")
print(msgs)