60 lines
3.6 KiB
Python
60 lines
3.6 KiB
Python
"""Small synthetic real gateway probe; no chat sender or client config writes."""
|
|
import base64
|
|
import io
|
|
import json
|
|
import sys
|
|
import time
|
|
import uuid
|
|
from pathlib import Path
|
|
from urllib import request,error
|
|
|
|
root=Path(sys.argv[1]).resolve()
|
|
sys.path.insert(0,str(root))
|
|
import backend_client
|
|
settings=backend_client.load_settings()
|
|
gateway=settings.get('gateway') or {}
|
|
token=backend_client.desktop_access_token()
|
|
mode=sys.argv[2]
|
|
nonce='SYNTHETIC-AUDIT-'+uuid.uuid4().hex[:10]
|
|
if mode=='context':
|
|
messages=[{'role':'system','content':'你是测试助手。这是合成接口验收,不是真实客户对话。只回答用户所问,不使用工具。'},
|
|
{'role':'user','content':'本次测试的包裹取件码为 '+nonce+',请记住。'},
|
|
{'role':'assistant','content':'已记住你提供的测试取件码。'},
|
|
{'role':'user','content':'请问我刚才提供的取件码是什么?只回答完整取件码。'}]
|
|
else:
|
|
from PIL import Image,ImageDraw,ImageFont
|
|
image=Image.new('RGB',(1000,330),'white')
|
|
draw=ImageDraw.Draw(image)
|
|
font=ImageFont.truetype('C:/Windows/Fonts/arial.ttf',36)
|
|
draw.text((35,45),'SYNTHETIC VISION TEST',fill='black',font=font)
|
|
draw.text((35,150),nonce,fill='black',font=font)
|
|
buffer=io.BytesIO();image.save(buffer,format='PNG')
|
|
image.save(Path(__file__).parent/'synthetic-vision.png')
|
|
messages=[{'role':'system','content':'这是合成图片识别测试。请按问题回答,不使用工具。'},
|
|
{'role':'user','content':[{'type':'text','text':'读出图片第二行的完整测试代码,只返回该代码。'},
|
|
{'type':'image_url','image_url':{'url':'data:image/png;base64,'+base64.b64encode(buffer.getvalue()).decode()}}]}]
|
|
if '--compatible-context' in sys.argv:
|
|
import model_protocol
|
|
assert mode=='context'
|
|
messages=[{'role':'user','content':model_protocol.dify_query(messages)}]
|
|
payload={'messages':messages,'task_id':'recognition-audit-'+uuid.uuid4().hex,'purpose':'chat',
|
|
'customer_text':'合成上下文验收:请返回此前取件码。' if mode=='context' else '合成视觉验收:读出图中测试代码。'}
|
|
started=time.monotonic()
|
|
req=request.Request(gateway['url'],data=json.dumps(payload,ensure_ascii=False).encode(),
|
|
headers={'Authorization':'Bearer '+token,'Content-Type':'application/json','X-Device-Id':str(settings.get('device_id') or 'synthetic-audit')},method='POST')
|
|
result={'root':str(root),'mode':mode,'synthetic_only':True,'task_id':payload['task_id'],'expected':nonce,'compatible_context':('--compatible-context' in sys.argv)}
|
|
try:
|
|
with request.urlopen(req,timeout=65) as response:
|
|
data=json.load(response)
|
|
result.update(http_status=response.status,reply_matches_expected=nonce in str(data.get('reply') or ''),
|
|
reply_excerpt=str(data.get('reply') or '')[:1200],chosen=data.get('chosen'),knowledge=data.get('knowledge'),judge_risk=(data.get('judge') or {}).get('risk'),
|
|
candidates=[{'provider':item.get('provider'),'reply_excerpt':str(item.get('text') or '')[:1200],'reply_matches_expected':nonce in str(item.get('text') or ''),
|
|
'has_error':bool(item.get('error'))} for item in data.get('candidates',[])])
|
|
except error.HTTPError as exc:
|
|
result.update(http_status=exc.code,error_type=type(exc).__name__)
|
|
except Exception as exc:
|
|
result.update(error_type=type(exc).__name__)
|
|
result['elapsed_seconds']=round(time.monotonic()-started,2)
|
|
out=Path(sys.argv[3]);out.write_text(json.dumps(result,ensure_ascii=False,indent=2),encoding='utf-8')
|
|
print(json.dumps(result,ensure_ascii=False))
|