Add profile-aware image reference editing
This commit is contained in:
1 parent
67cf57a5b7
commit
f1ccb02e10
11 files changed
+156
-21
No files matched your search
+16
-4
@@ -183,6 +183,15 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
if self.command!='POST':raise APIError('Route nicht gefunden.',404)
|
||||
if ep.video and ep.scheduler.gpu_mode!='llm' and self.path!='/v1/audio/transcriptions':raise APIError('Video-Modus aktiv; Chat-, Bild- und TTS-Aufträge sind gesperrt. Auf LLM zurückschalten.',503,'video_mode_active')
|
||||
if self.path=='/v1/audio/transcriptions':return self.transcription(ep)
|
||||
if self.path=='/v1/images/edits':
|
||||
from image_upload import read_image_upload
|
||||
try:
|
||||
fields,images=read_image_upload(self)
|
||||
if not images:raise ValueError('Mindestens ein Referenzbild erforderlich.')
|
||||
if set(fields)-{'model','prompt','size','n','response_format'}:raise ValueError('Nicht unterstützte Bildparameter.')
|
||||
fields['n']=int(fields.get('n','1'))
|
||||
return self.image(ep,fields,images)
|
||||
except ValueError as exc:raise APIError(str(exc)) from None
|
||||
if self.path not in ('/v1/chat/completions','/v1/images/generations','/v1/audio/speech'):raise APIError('Route nicht implementiert.',404)
|
||||
if self.headers.get('Transfer-Encoding'):raise APIError('Chunked Upload wird nicht unterstützt.')
|
||||
try:length=int(self.headers.get('Content-Length','0'))
|
||||
@@ -286,18 +295,21 @@ class APIHandler(BaseHTTPRequestHandler):
|
||||
self.wfile.write(chunk);self.wfile.flush()
|
||||
raise InferenceError('Zeitlimit der Streaming-Antwort überschritten.')
|
||||
finally:conn.close()
|
||||
def image(self,ep,data):
|
||||
def image(self,ep,data,reference_images=None):
|
||||
if set(data)-{'model','prompt','n','size','response_format','user'}:raise APIError('Nicht unterstützte Bildparameter. Schritte/Guidance/Seed stehen im Profil.')
|
||||
if data.get('n',1)!=1 or data.get('response_format','b64_json')!='b64_json':raise APIError('Unterstützt werden n=1 und response_format=b64_json.')
|
||||
profile=ep.find_profile(data.get('model'),'image');params=profile['parameters']
|
||||
from profiles import image_capabilities
|
||||
if len(reference_images or [])>image_capabilities(profile.get('model'))['reference_images']:raise APIError('Das aktive Bildprofil unterstützt diese Anzahl Referenzbilder nicht.')
|
||||
size=data.get('size')
|
||||
if size is not None and (not isinstance(size,str) or (size!='auto' and not re.fullmatch(r'[1-9][0-9]{1,4}x[1-9][0-9]{1,4}',size))):raise APIError('size muss auto oder eine Auflösung wie 1024x1024 sein.')
|
||||
# The selected profile owns resource limits; client size is only a preference.
|
||||
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(('image',),allowed=allowed):
|
||||
return self.generate_image(ep,profile,data)
|
||||
def generate_image(self,ep,profile,data):
|
||||
job=ep.images.start(profile['id'],data.get('prompt'),reserved=True)
|
||||
return self.generate_image(ep,profile,data,reference_images or [])
|
||||
def generate_image(self,ep,profile,data,reference_images=None):
|
||||
options={'reference_images':reference_images} if reference_images else {}
|
||||
job=ep.images.start(profile['id'],data.get('prompt'),reserved=True,**options)
|
||||
deadline=time.monotonic()+2100
|
||||
while time.monotonic()<deadline:
|
||||
current=ep.images.status()['job']
|
||||
|
||||
Reference in new issue
Block a user