import json import time import urllib.request from pathlib import Path key = Path('/run/secrets/qwen_api_key').read_text().strip() base = 'http://127.0.0.1:8000' headers = {'Authorization': 'Bearer ' + key, 'Content-Type': 'application/json'} def request(path, payload=None): data = None if payload is None else json.dumps(payload).encode() with urllib.request.urlopen(urllib.request.Request(base + path, data=data, headers=headers), timeout=900) as response: return json.load(response) print(json.dumps({'models': request('/v1/models')}, ensure_ascii=False), flush=True) cases = [ ('arithmetic', '计算 17 × 19,只给出数字。', '323'), ('chinese', '请用中文简短说明为什么天空是蓝色的。', None), ] for name, prompt, expected in cases: start = time.monotonic() result = request('/v1/chat/completions', { 'model': 'qwen3.8-flash-next', 'messages': [{'role': 'user', 'content': prompt}], 'temperature': 0, 'max_tokens': 1024, 'reasoning_effort': 'low', }) choice = result['choices'][0] content = choice['message'].get('content') or '' record = {'test': name, 'seconds': round(time.monotonic()-start, 2), 'content': content, 'finish_reason': choice['finish_reason'], 'usage': result.get('usage')} print(json.dumps(record, ensure_ascii=False), flush=True) assert content.strip(), 'No final answer' if expected: assert expected in content, 'Arithmetic mismatch' p={'model':'qwen3.8-flash-next','messages':[{'role':'user','content':'请调用 get_weather 查询上海的天气,不要自行编造。'}],'tools':[{'type':'function','function':{'name':'get_weather','description':'查询城市天气','parameters':{'type':'object','properties':{'city':{'type':'string'}},'required':['city']}}}],'tool_choice':'auto','temperature':0,'max_tokens':512,'reasoning_effort':'low'} t=time.monotonic();r=request('/v1/chat/completions', p);m=r['choices'][0]['message'];print(json.dumps({'test':'tool_call','seconds':time.monotonic()-t,'message':m},ensure_ascii=False),flush=True) assert m.get('tool_calls') and m['tool_calls'][0]['function']['name']=='get_weather' print('TOOL_TEST_PASS',flush=True) print("SMOKE_TEST_PASS", flush=True)