Isolate client reasoning normalization in API compatibility adapter
This commit is contained in:
+11
-6
@@ -10,6 +10,7 @@ import socket
|
||||
import threading
|
||||
import time
|
||||
from http.server import BaseHTTPRequestHandler,ThreadingHTTPServer
|
||||
from api_compat import normalize_chat,CompatibilityError
|
||||
from inference import InferenceError
|
||||
from stt import read_upload
|
||||
|
||||
@@ -136,9 +137,15 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
protocol_version='HTTP/1.1'
|
||||
def setup(self):super().setup();self.connection.settimeout(15);self.sent=False
|
||||
def log_message(self,*args):pass
|
||||
def compatibility_headers(self):
|
||||
info=getattr(self,'compatibility',{})
|
||||
if info:
|
||||
self.send_header('X-Athena-Reasoning-Requested',info['requested'])
|
||||
self.send_header('X-Athena-Reasoning-Effective',info['effective'])
|
||||
self.send_header('X-Athena-Reasoning-Semantics',info['semantics'])
|
||||
def send(self,payload,status=200):
|
||||
body=json.dumps(payload).encode();self.sent=True
|
||||
self.send_response(status);self.send_header('Content-Type','application/json');self.send_header('Content-Length',str(len(body)));self.send_header('Cache-Control','no-store');self.send_header('Connection','close');self.end_headers();self.wfile.write(body);self.close_connection=True
|
||||
self.send_response(status);self.compatibility_headers();self.send_header('Content-Type','application/json');self.send_header('Content-Length',str(len(body)));self.send_header('Cache-Control','no-store');self.send_header('Connection','close');self.end_headers();self.wfile.write(body);self.close_connection=True
|
||||
def failure(self,exc):
|
||||
if self.sent:return
|
||||
self.send({'error':{'message':str(exc),'type':getattr(exc,'code','server_error'),'param':None,'code':getattr(exc,'code','worker_unavailable')}},getattr(exc,'status',503))
|
||||
@@ -211,9 +218,8 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
self.sent=True;self.send_response(200);self.send_header('Content-Type','audio/wav');self.send_header('Content-Length',str(len(body)));self.send_header('Cache-Control','no-store');self.send_header('Connection','close');self.end_headers();self.wfile.write(body);return
|
||||
raise APIError('TTS-Zeitlimit überschritten.',504)
|
||||
def chat(self,ep,data):
|
||||
supported={'model','messages','stream','stream_options','temperature','top_p','top_k','max_tokens','max_completion_tokens','stop','seed','tools','tool_choice','parallel_tool_calls','response_format','presence_penalty','frequency_penalty','logprobs','top_logprobs','user','n','reasoning_effort'}
|
||||
if set(data)-supported:raise APIError('Nicht unterstützte Chat-Felder: '+', '.join(sorted(set(data)-supported)))
|
||||
if 'reasoning_effort' in data and data['reasoning_effort'] is not None and (not isinstance(data['reasoning_effort'],str) or data['reasoning_effort'] not in ('none','minimal','low','medium','high','xhigh')):raise APIError('Ungültiger reasoning_effort-Wert.')
|
||||
try:data,self.compatibility=normalize_chat(data)
|
||||
except CompatibilityError as exc:raise APIError(str(exc)) from None
|
||||
if type(data.get('stream',False)) is not bool:raise APIError('stream muss true oder false sein.')
|
||||
if data.get('n',1)!=1:raise APIError('Zunächst wird n=1 unterstützt.')
|
||||
messages=data.get('messages')
|
||||
@@ -241,7 +247,6 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
def allowed():return ep.allowed() and any(p['id']==profile['id'] and p['revision']==profile['revision'] and p['enabled'] for p in ep.rows())
|
||||
with ep.scheduler.lease(key,profile['parameters']['slots'],lambda:ep.worker.ensure(profile),allowed=allowed):
|
||||
body=dict(data)
|
||||
if body.get('reasoning_effort') is None:body.pop('reasoning_effort',None)
|
||||
for field in ('temperature','top_p','top_k'):body.setdefault(field,profile['parameters'][field])
|
||||
conn,key=ep.worker.connect()
|
||||
try:
|
||||
@@ -254,7 +259,7 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
if len(raw)>16*1024*1024:raise InferenceError('Modellantwort überschreitet 16 MiB.')
|
||||
return self.send(json.loads(raw))
|
||||
self.sent=True;self.connection.settimeout(30)
|
||||
self.send_response(200);self.send_header('Content-Type','text/event-stream');self.send_header('Cache-Control','no-store');self.send_header('Connection','close');self.end_headers()
|
||||
self.send_response(200);self.compatibility_headers();self.send_header('Content-Type','text/event-stream');self.send_header('Cache-Control','no-store');self.send_header('Connection','close');self.end_headers()
|
||||
deadline=time.monotonic()+600
|
||||
while time.monotonic()<deadline:
|
||||
chunk=response.read1(8192)
|
||||
|
||||
Reference in New Issue
Block a user