WENIGER SUCHEN. BESSER PROMPTEN.
Deine besten Worte.
Sammeln, verfeinern und genau dann wiederfinden, wenn du sie brauchst.
diff --git a/README.md b/README.md
index 750d107..e5ec1a6 100644
--- a/README.md
+++ b/README.md
@@ -140,3 +140,11 @@ Der interne Python-Paketname `atelier` ist nur ein Implementierungsdetail.
## Stand und Grenzen
Erste eigenständige Version. Die KI-Überarbeitung ist absichtlich ein manueller Entwurf; ein grafischer Wort-für-Wort-Diff ist noch nicht enthalten. Versionsvorschau und Wiederherstellung sind vorhanden. Die Tests nutzen einen simulierten OpenAI-kompatiblen Modellserver; ein konkretes lokales Modell muss beim Einrichten noch geprüft werden. Docker/Unraid wird über die beiliegenden Dateien vorbereitet, ein echter Container-Test muss auf einer Maschine mit Docker erfolgen.
+
+## KI-Selbstprüfung und Diagnose
+
+Die Prüfung stammt vom selben Modell und ist keine unabhängige Verifikation. Historische Befunde zum ersten Entwurf sind getrennt von Befunden zum aktuellen Vorschlag. Bei Fehlern bleibt der Entwurf erhalten; die Meldung benennt den fehlgeschlagenen Schritt und eine Diagnose-ID. „Aktuellen Vorschlag erneut prüfen“ führt genau einen Prüfanruf ohne automatische Textänderung aus.
+
+Zusätzlich vergleicht Code erkennbare `{{Platzhalter}}`, explizite Portangaben und Pfadmuster. Unterschiede sind Hinweise, keine sicheren Fehler: Auch gewünschte Änderungen können markiert werden; nicht jedes mögliche Pfadformat wird erkannt. Ein Bearbeiten der Vergleichstexte setzt die Anzeige auf ungeprüft zurück.
+
+Containerlogs enthalten für Modellaufrufe ausschließlich Diagnose-ID, Verarbeitungsschritt, Dauer, HTTP-Status und Fehlerklasse. Prompt-/Antwortinhalte, API-Keys und Endpoint-URLs werden nicht durch diese Diagnose protokolliert. Drittanbieter-HTTP-Info-Logs sind deaktiviert. Der bisherige 90-Sekunden-Timeout bleibt unverändert.
diff --git a/atelier/app.py b/atelier/app.py
index 7ee8109..a9a63a1 100644
--- a/atelier/app.py
+++ b/atelier/app.py
@@ -67,11 +67,19 @@ class Improvement(BaseModel):
instruction: str = Field(default='Formuliere klarer, präziser und hilfreicher. Bewahre die Absicht.', max_length=4000)
+class Recheck(Improvement):
+ draft: str = Field(min_length=1, max_length=60000)
+
+
class Login(BaseModel):
token: str = Field(max_length=500)
def create_app(data_dir=None, provider_transport=None):
+ # Suppress third-party request URLs; our provider logs only allowlisted metadata.
+ import logging
+ logging.getLogger('httpx').setLevel(logging.WARNING)
+ logging.getLogger('httpcore').setLevel(logging.WARNING)
root = Path(data_dir or os.environ.get('DATA_DIR', './data'))
root.mkdir(parents=True, exist_ok=True)
os.chmod(root, 0o700)
@@ -313,6 +321,10 @@ def create_app(data_dir=None, provider_transport=None):
async def improve(body: Improvement):
return await provider().improve_checked(body.body, body.instruction)
+ @app.post('/api/recheck')
+ async def recheck(body: Recheck):
+ return await provider().recheck(body.body, body.instruction, body.draft)
+
@app.post('/api/organize')
async def organize(body: Improvement):
return await provider().organize(body.body, list_categories())
diff --git a/atelier/provider.py b/atelier/provider.py
index f297a79..113d2fe 100644
--- a/atelier/provider.py
+++ b/atelier/provider.py
@@ -1,15 +1,42 @@
import hashlib
import json
import math
+import logging
+import re
+import time
+import uuid
from urllib.parse import urlsplit
import httpx
+logger = logging.getLogger('uvicorn.error')
+
+
class ProviderError(Exception):
pass
+def literal_checks(original, draft):
+ patterns = {
+ 'Platzhalter': r'\{\{[^{}\n]+\}\}',
+ 'Port': r'(?i)\bport\s*[:=]?\s*(\d{1,5})\b|:(\d{2,5})\b',
+ 'Pfad': r'(?{if(!organization)return;$('p-category').valu
function renderReview(report) {
const box=$('ai-review');box.replaceChildren();
- const titles={passed:'Prüfung: Keine Abweichungen erkannt',corrected:'Prüfung: Abweichungen korrigiert; erneut geprüft',issues:'Prüfung: Abweichungen verbleiben',unchecked:'Nicht geprüft – keine abgeschlossene Verifikation'};
+ const titles={passed:'KI-Selbstprüfung: Keine Abweichungen erkannt',corrected:'Korrigierter Entwurf: KI-Selbstprüfung abgeschlossen',issues:'KI-Selbstprüfung: Abweichungen im aktuellen Vorschlag',unchecked:report?.draft_kind==='corrected'?'Korrigierter Entwurf – Abschlussprüfung fehlgeschlagen':'Aktueller Entwurf – KI-Selbstprüfung nicht abgeschlossen'};
const heading=document.createElement('strong');heading.textContent=titles[report?.status]||titles.unchecked;box.append(heading);
if(report?.warning){const p=document.createElement('p');p.textContent=report.warning;box.append(p);}
function issues(label, entries){if(!entries?.length)return;const details=document.createElement('details');details.open=true;const summary=document.createElement('summary');summary.textContent=label+' ('+entries.length+')';details.append(summary);const ul=document.createElement('ul');for(const issue of entries){const li=document.createElement('li');li.textContent=issue.description;for(const [key,title]of [['original_quote','Original'],['draft_quote','Vorschlag']]){if(issue[key]){const p=document.createElement('p');p.textContent=title+': „'+issue[key]+'“';li.append(p);}}ul.append(li);}details.append(ul);box.append(details);}
- issues('Befunde der ersten Prüfung',report?.initial_issues);
- if(report?.status==='issues')issues('Weiterhin erkannte Abweichungen',report.issues);
- const hint=document.createElement('p');hint.textContent='Modellprüfung, keine Garantie. Bitte den Vorschlag vor dem Speichern selbst prüfen.';box.append(hint);
+ if(report?.draft_kind==='corrected')issues('Historische Befunde zum ERSTEN Entwurf (vor der Korrektur)',report?.initial_issues);
+ else if(report?.status!=='issues')issues('Befunde zum angezeigten Entwurf',report?.initial_issues);
+ issues('Code-Prüfung: Unterschiede im aktuellen Vorschlag – bitte beurteilen',report?.literal_issues);
+ if(report?.status==='issues')issues('Befunde zum AKTUELLEN Vorschlag',report.issues);
+ const hint=document.createElement('p');hint.textContent='Selbstprüfung durch dasselbe Modell, keine unabhängige Verifikation. Die Code-Prüfung sucht nur erkennbare Platzhalter, Ports und Pfade; gewünschte Änderungen können ebenfalls markiert werden. Bitte selbst vergleichen.';box.append(hint);
}
bind('ai-draft','input',()=>renderReview({status:'unchecked',warning:'Vorschlag manuell geändert; diese Fassung wurde nicht geprüft.'}));
+
+bind('recheck-ai','click',()=>busy($('recheck-ai'),async()=>{
+ const generation=editorGeneration;
+ const original=$('p-body').value, instruction=$('ai-instruction').value, draft=$('ai-draft').value;
+ if(!original.trim()||!draft.trim())throw new Error('Original und Vorschlag dürfen nicht leer sein.');
+ const result=await api('/recheck',{method:'POST',body:JSON.stringify({body:original,instruction,draft})});
+ if(generation!==editorGeneration||!$('editor').open)return;
+ if(original!==$('p-body').value||instruction!==$('ai-instruction').value||draft!==$('ai-draft').value){renderReview({status:'unchecked',warning:'Text während der Prüfung geändert. Bitte erneut prüfen.'});return;}
+ renderReview(result.review);
+}));
+for(const id of ['p-body','ai-instruction'])bind(id,'input',()=>{if(!$('ai-result').classList.contains('hidden'))renderReview({status:'unchecked',warning:'Vergleichsgrundlage geändert. Bitte erneut prüfen.'});});
diff --git a/atelier/static/index.html b/atelier/static/index.html
index 62b46a0..d4be1e1 100644
--- a/atelier/static/index.html
+++ b/atelier/static/index.html
@@ -6,7 +6,7 @@
WENIGER SUCHEN. BESSER PROMPTEN. Sammeln, verfeinern und genau dann wiederfinden, wenn du sie brauchst.Deine besten Worte.