"""Small live API acceptance suite; writes evidence without API credentials.""" import argparse import json import time import urllib.request from pathlib import Path p = argparse.ArgumentParser() p.add_argument('--url', default='http://127.0.0.1:8000') p.add_argument('--key-file', type=Path, default=Path(__file__).resolve().parents[1] / 'secrets/api-key') p.add_argument('--output', type=Path, required=True) args = p.parse_args() key = args.key_file.read_text().strip() def request(path, body=None): payload = None if body is None else json.dumps(body, ensure_ascii=False).encode() req = urllib.request.Request(args.url + path, data=payload, headers={'Authorization': 'Bearer ' + key, 'Content-Type': 'application/json'}) return urllib.request.urlopen(req, timeout=600) args.output.parent.mkdir(parents=True, exist_ok=True) with args.output.open('x') as out: def record(data): line = json.dumps(data, ensure_ascii=False) out.write(line + '\n'); out.flush(); print(line, flush=True) record({'models': json.load(request('/v1/models'))}) for name, text, expected in [ ('math', 'Compute 17 * 19. Reply with only the integer.', '323'), ('chinese', '请只回复:模型已就绪', '模型已就绪'), ]: body = dict(model='qwen3.8-flash-next', messages=[dict(role='user', content=text)], temperature=0, reasoning_effort='low', max_tokens=1024, stream=True, stream_options={'include_usage': True}) start = time.monotonic(); first = None; content = ''; reasoning = ''; usage = {}; finish = None with request('/v1/chat/completions', body) as response: for raw in response: if not raw.startswith(b'data: '): continue data = raw[6:].strip() if data == b'[DONE]': break item = json.loads(data) if item.get('usage'): usage = item['usage'] for choice in item.get('choices', []): delta = choice.get('delta', {}) c = delta.get('content') or '' r = delta.get('reasoning') or delta.get('reasoning_content') or '' if (c or r) and first is None: first = time.monotonic() content += c; reasoning += r finish = choice.get('finish_reason') or finish elapsed = time.monotonic() - start passed = content.strip() == expected and finish == 'stop' record(dict(test=name, passed=passed, content=content, reasoning_chars=len(reasoning), ttft_s=None if first is None else first-start, elapsed_s=elapsed, finish_reason=finish, usage=usage)) if not passed: raise SystemExit('Acceptance failure: ' + name) body = dict(model='qwen3.8-flash-next', temperature=0, reasoning_effort='low', max_tokens=1024, messages=[dict(role='user',content='Use get_weather to check the weather in Shanghai.')], tools=[dict(type='function',function=dict(name='get_weather',description='Get current weather', parameters=dict(type='object',properties={'city':{'type':'string'}},required=['city'])))], tool_choice='auto') result = json.load(request('/v1/chat/completions',body)) calls = result['choices'][0]['message'].get('tool_calls') or [] passed = bool(calls) and calls[0]['function']['name']=='get_weather' record(dict(test='tool',passed=passed,response=result)) if not passed: raise SystemExit('Tool acceptance failure')