From e35c7518db1f5c23c732f3932b62e6778f24c95a Mon Sep 17 00:00:00 2001 From: Sascha Wolf Date: Wed, 23 Sep 2026 10:31:55 +0200 Subject: [PATCH] feat(ki): Einstellungen -> KI mit OpenAI-Schluessel und Modellwahl Neuer Admin-Reiter "KI": zeigt die letzten vier Zeichen des hinterlegten OpenAI-Schluessels samt Quelle, nimmt einen neuen an (vorher gegen /v1/models geprueft) und laesst je Einsatzzweck das Modell per Dropdown waehlen - Scanner-Bewertung, Abgleich "bereits beworben", erweiterte Suche. Die Auswahl kommt live von OpenAI, Vorgaben sind die bisher fest verdrahteten Modelle. Reasoning-Modelle bekommen reasoning_effort statt temperature, damit ein Wechsel keinen 400er ausloest. Schluesselfeld aus dem Scanner-Reiter entfernt; Doku in docs/14-ki.md. Co-Authored-By: Claude Opus 5.5 --- docs/01-architektur.md | 2 +- docs/02-datenmodell.md | 3 + docs/03-scanner.md | 7 +- docs/06-betrieb.md | 3 +- docs/07-anleitung-benutzer.md | 15 +- docs/09-quellcode.md | 24 ++ docs/12-suche.md | 7 +- docs/14-ki.md | 102 +++++++ docs/README.md | 139 ++++----- docs/bilder/einstellungen-ki.png | Bin 0 -> 174565 bytes server/.env.example | 4 +- server/package.json | 2 +- server/src/ai.js | 236 ++++++++++++-- server/src/routes/ai.js | 77 +++++ server/src/routes/search.js | 8 +- server/src/scanner/services/appliedCheck.js | 10 +- server/src/scanner/services/matchingEngine.js | 12 +- server/src/server.js | 3 + server/test/ai.test.mjs | 43 +++ src/App.tsx | 2 +- src/components/settings/AiSettings.tsx | 287 ++++++++++++++++++ src/components/settings/ScannerSettings.tsx | 29 +- src/components/settings/Settings.tsx | 3 + src/lib/api.ts | 51 ++++ src/lib/scannerApi.ts | 2 - src/types.ts | 3 +- 26 files changed, 930 insertions(+), 144 deletions(-) create mode 100644 docs/14-ki.md create mode 100644 docs/bilder/einstellungen-ki.png create mode 100644 server/src/routes/ai.js create mode 100644 server/test/ai.test.mjs create mode 100644 src/components/settings/AiSettings.tsx diff --git a/docs/01-architektur.md b/docs/01-architektur.md index 44b93db..28014fd 100644 --- a/docs/01-architektur.md +++ b/docs/01-architektur.md @@ -97,7 +97,7 @@ Einzelheiten: [13 Anmeldung über Microsoft](13-anmeldung-sso.md). ```mermaid flowchart TD L["Anmeldung"] --> R{"Rolle"} - R -->|admin| A["Dashboard, Akquise, Opportunities, Interviews, Kontakte, Mails, Scanner
Einstellungen: Nutzerverwaltung, Mein Konto, Akquise, Postfach, Scanner, Whisper"] + R -->|admin| A["Dashboard, Akquise, Opportunities, Interviews, Kontakte, Mails, Scanner
Einstellungen: Nutzerverwaltung, Mein Konto, Akquise, Postfach, Anmeldung, Scanner, KI, Whisper"] R -->|user| U["Dashboard, Akquise, Opportunities, Interviews, Kontakte, Mails, Scanner
Einstellungen: Mein Konto, Akquise, Whisper"] ``` diff --git a/docs/02-datenmodell.md b/docs/02-datenmodell.md index cc93862..0e99f47 100644 --- a/docs/02-datenmodell.md +++ b/docs/02-datenmodell.md @@ -382,6 +382,9 @@ erDiagram - **`settings` ist ein Schlüssel-Wert-Speicher.** Geheimnisse (`openai_api_key`, `smtp_pass`) liefert die API nur maskiert als `********` aus; ein leeres oder maskiertes Feld beim Speichern lässt den gespeicherten Wert unberührt. + `openai_api_key` wird seit dem 23.09.2026 unter *Einstellungen → KI* gepflegt + (siehe [14 KI](14-ki.md)); die Modellwahl dazu steht in `crm_settings` als + `ai_model_matching`, `ai_model_applied` und `ai_model_search`. ## Statuswege diff --git a/docs/03-scanner.md b/docs/03-scanner.md index e3f034f..91c0697 100644 --- a/docs/03-scanner.md +++ b/docs/03-scanner.md @@ -90,8 +90,9 @@ flowchart TD Entscheidungen dahinter: -- **Eigenes Modell.** Die Bewertung CV gegen Projekt bleibt bei `gpt-4o-mini`; - der Abgleich nutzt `gpt-5.6-luna` (Konstante `APPLIED_CHECK_MODEL`). Er muss +- **Eigenes Modell.** Die Bewertung CV gegen Projekt nutzt als Vorgabe + `gpt-4o-mini`, der Abgleich `gpt-5.6-luna` - beide umstellbar unter + *Einstellungen → KI* (siehe [14 KI](14-ki.md)). Der Abgleich muss umformulierte Ausschreibungen als dieselbe erkennen und ähnliche Rollen bei anderem Kunden auseinanderhalten - das ist ein Urteil, kein Textvergleich. Der Schlüssel ist derselbe `openai_api_key`. @@ -284,7 +285,7 @@ Zertifikatswarnung. Der DNS-Eintrag muss beim Anbieter gelöscht werden. | Unpassend | `ScannerRejected.tsx` | Treffer mit Status `rejected` | | Suchagenten | `ScannerAgents.tsx` | Beraterprofile, CV-Upload | | Börsen-Konten | `ScannerPortals.tsx` | Verbindungsstatus, Zugangsdaten, Cookie-Import | -| Einstellungen | `settings/ScannerSettings.tsx` | Intervall, Schwellenwerte, Abgleich mit Akquise/Opportunities, OpenAI, Ton, E-Mail | +| Einstellungen | `settings/ScannerSettings.tsx` | Intervall, Schwellenwerte, Abgleich mit Akquise/Opportunities, Ton, E-Mail (Schlüssel und Modelle: `settings/AiSettings.tsx`) | **Wichtig zum Ton:** Er hängt an der Dashboard-Komponente. Wer auf einen anderen Menüpunkt wechselt, hört nichts - die Komponente wird ausgebaut und die diff --git a/docs/06-betrieb.md b/docs/06-betrieb.md index 08f3639..5b2d74f 100644 --- a/docs/06-betrieb.md +++ b/docs/06-betrieb.md @@ -129,7 +129,8 @@ entfallen. | --- | --- | | Anmeldung schlägt fehl | `journalctl -u perinco-crm-backend -n 50`, `JWT_SECRET` gesetzt? | | Scanner-Reiter leer, 500er | `[Scanner] Datenbank nicht erreichbar` im Journal | -| Kein Treffer trotz Scan | `scanning_active`, aktive Agenten mit CV, OpenAI-Key gesetzt | +| Kein Treffer trotz Scan | `scanning_active`, aktive Agenten mit CV, OpenAI-Key gesetzt (*Einstellungen → KI*) | +| KI-Fehler „model not found“ | Modell unter *Einstellungen → KI* auf eines aus der Liste stellen | | Portal `expired` | Cookies neu importieren (Cookie-Editor) | | `Target page ... has been closed` | Dienst wurde mitten im Scrapen neu gestartet | | Backend stirbt beim Scrapen | `MemoryMax` zu klein, `systemctl show ... -p MemoryCurrent` | diff --git a/docs/07-anleitung-benutzer.md b/docs/07-anleitung-benutzer.md index cff1417..1f3330a 100644 --- a/docs/07-anleitung-benutzer.md +++ b/docs/07-anleitung-benutzer.md @@ -949,7 +949,8 @@ Sitzung kommt derzeit nur über den Cookie-Import. | **Mein Konto** | alle | Foto, Terminfarbe, Passwort ändern | | **Akquise** | alle | Inhalte der Auswahllisten *Von*, *Kanal*, *Berater* | | **Postfach** | Admin | Verbindung zu Microsoft 365, Abgleich, Kontaktübernahme | -| **Scanner** | Admin | Suchintervall, Schwellenwerte, KI-Schlüssel, Ton, E-Mail | +| **Scanner** | Admin | Suchintervall, Schwellenwerte, Ton, E-Mail | +| **KI** | Admin | OpenAI-Schlüssel, Modell je Einsatzzweck | | **Whisper** | alle | Spracherkennung für das Diktat einrichten | Im Reiter **Akquise** stehen die drei Auswahllisten des Akquise-Formulars, jede @@ -976,6 +977,18 @@ Unter **Abgleich mit Akquise und Opportunities** lässt sich die Markierung ein Akquise-Eintrag oder eine Opportunity höchstens sein darf, um verglichen zu werden - in Tagen oder Wochen, Vorgabe zwei Wochen. +Im Reiter **KI** steht links der **OpenAI-Schlüssel**. Zu sehen ist nur sein +Ende (etwa `sk-…x7Qa`) und woher er stammt. Einen neuen trägst du unter *Neuer +Schlüssel* ein und klickst **Speichern** - das CRM fragt damit kurz bei OpenAI an +und übernimmt ihn nur, wenn OpenAI ihn annimmt. Bis dahin bleibt der alte gültig. + +Rechts wählst du je Einsatzzweck das **Modell**: für die Bewertung im Scanner, +für den Abgleich „bereits beworben!“ und für die erweiterte Suche. Die Liste +kommt direkt von OpenAI; *(Vorgabe)* markiert das ursprüngliche Modell. Nach +**Modellwahl speichern** gilt die Wahl ab dem nächsten Aufruf. + +![Einstellungen, Reiter KI](bilder/einstellungen-ki.png) + Im Reiter **Postfach** steht oben, ob die Verbindung zu Microsoft 365 steht. **Verbindung testen** prüft beides: die Anmeldung *und* den tatsächlichen Zugriff auf `crm@perinco.de`. Schlägt etwas fehl, nennt die Meldung den diff --git a/docs/09-quellcode.md b/docs/09-quellcode.md index c1bc3e5..9eeca4f 100644 --- a/docs/09-quellcode.md +++ b/docs/09-quellcode.md @@ -231,6 +231,30 @@ Eigenheiten, die man kennen muss: Funktionen `mailConfigured()` und `ssoConfigured()` - die Prüfung muss in die Datenbank sehen. +### `server/src/ai.js` + +OpenAI-Schlüssel, Modellwahl je Einsatzzweck und der Aufruf der erweiterten +Suche. Gepflegt unter *Einstellungen → KI*, Details in [14 KI](14-ki.md). + +| Export | Zweck | +| --- | --- | +| `aiKey()` / `aiConfigured()` | gültiger Schlüssel, Datenbank vor `.env` | +| `keyStatus()` | Quelle und letzte vier Zeichen - nie der ganze Schlüssel | +| `verifyKey()` / `saveKey()` / `clearKey()` | Probe bei OpenAI, schreiben, zurücknehmen | +| `AI_PURPOSES`, `modelFor(zweck)` | Einsatzzwecke mit Vorgabe; eingestelltes Modell oder Vorgabe | +| `modelSettings()` / `saveModels()` / `availableModels()` | Modellwahl lesen, schreiben, Auswahlliste von OpenAI | +| `isReasoningModel()` | `reasoning_effort` statt `temperature`, in `test/ai.test.mjs` geprüft | +| `askModelJson()` | ein Chat-Completions-Aufruf mit JSON-Antwort | + +Eigenheiten, die man kennen muss: + +* Der Schlüssel liegt in der **Scanner**-Datenbank (`settings.openai_api_key`), + die Modellwahl in der **CRM**-Datenbank (`crm_settings.ai_model_*`). Der + Schlüssel stand dort schon immer; die Modellwahl ist CRM-weit. +* Scanner-Dienste (`matchingEngine.js`, `appliedCheck.js`) holen Schlüssel und + Modell ebenfalls hier - keiner liest `openai_api_key` mehr selbst. +* Kein Zwischenspeicher: jede Änderung wirkt beim nächsten Aufruf. + ### `server/src/sso/` Anmeldung über Microsoft Entra, fachlich in diff --git a/docs/12-suche.md b/docs/12-suche.md index 91e7c2e..6f720f0 100644 --- a/docs/12-suche.md +++ b/docs/12-suche.md @@ -99,11 +99,11 @@ werden: Die erweiterte Suche benutzt **denselben OpenAI-Schlüssel wie der Scanner** – `openai_api_key` in der Scanner-Tabelle `settings`, gepflegt unter -*Einstellungen → Scanner*, ersatzweise `OPENAI_API_KEY` aus der Umgebung. Ein +*Einstellungen → KI* (siehe [14 KI](14-ki.md)), ersatzweise `OPENAI_API_KEY` aus der Umgebung. Ein zweiter Schlüssel an zweiter Stelle wäre eine Quelle für den Fall „die eine Funktion geht, die andere nicht, und keiner weiß warum". -Modell: `gpt-4o-mini`, wie im Scanner. Fehlt der Schlüssel, antwortet der +Modell: einstellbar unter *Einstellungen → KI*, Vorgabe `gpt-4o-mini`. Fehlt der Schlüssel, antwortet der Endpunkt mit `503` und dem Hinweis auf die Einstellungen; die Volltextsuche bleibt davon unberührt. @@ -116,7 +116,8 @@ Scanner behält sein SDK, dort hängt mehr daran. | Datei | Aufgabe | | --- | --- | | `server/src/routes/search.js` | beide Endpunkte | -| `server/src/ai.js` | OpenAI-Aufruf, Schlüssel des Scanners | +| `server/src/ai.js` | OpenAI-Aufruf, Schlüssel, Modellwahl | +| `server/src/routes/ai.js` | Einstellungen → KI (siehe [14 KI](14-ki.md)) | | `server/src/routes/iconCrm.js` | `fetchIconContacts()` samt Zwischenspeicher | | `src/components/GlobalSearch.tsx` | das Feld, beide Modi, die Trefferliste | | `src/components/Header.tsx` | bindet es mittig in die Kopfleiste ein | diff --git a/docs/14-ki.md b/docs/14-ki.md new file mode 100644 index 0000000..345a469 --- /dev/null +++ b/docs/14-ki.md @@ -0,0 +1,102 @@ +# 14 KI: Schlüssel und Modelle + +Das CRM ruft OpenAI an drei Stellen auf. Schlüssel und Modell pflegen +Administratoren unter **Einstellungen → KI** - ohne SSH, ohne Neustart. + +![Einstellungen, Reiter KI: Schlüssel mit den letzten vier Zeichen, Modell je Einsatzzweck](bilder/einstellungen-ki.png) + +## Wo die KI arbeitet + +| Einsatzzweck | Code | Schlüssel in `crm_settings` | Vorgabe | +| --- | --- | --- | --- | +| Scanner: Bewertung Lebenslauf gegen Projekt | `scanner/services/matchingEngine.js` | `ai_model_matching` | `gpt-4o-mini` | +| Scanner: Abgleich „bereits beworben" | `scanner/services/appliedCheck.js` | `ai_model_applied` | `gpt-5.6-luna` | +| Erweiterte Suche | `routes/search.js` | `ai_model_search` | `gpt-4o-mini` (bzw. `OPENAI_MODEL`) | + +Die Vorgaben sind genau die Modelle, die vor der Einstellung fest im Code +standen. Wer nichts umstellt, merkt also nichts. Steht in `crm_settings` kein +oder ein ungültiger Eintrag, gilt die Vorgabe. + +```mermaid +flowchart LR + UI["Einstellungen → KI"] -->|"PUT /api/ai/key"| V{"GET /v1/models
mit neuem Schlüssel"} + V -->|"abgelehnt"| X["Fehlermeldung,
alter Schlüssel bleibt"] + V -->|"ok"| K[("perinco_scanner.settings
openai_api_key")] + UI -->|"PUT /api/ai/models"| M[("perinco_CRM.crm_settings
ai_model_*")] + K --> AI["server/src/ai.js
aiKey() / modelFor()"] + E["OPENAI_API_KEY
server/.env"] -.->|"nur wenn DB leer"| AI + M --> AI + AI --> S1["Scanner-Bewertung"] + AI --> S2["Abgleich bereits beworben"] + AI --> S3["Erweiterte Suche"] +``` + +## Schlüssel + +Es gibt **genau einen** OpenAI-Schlüssel für Scanner und CRM. Er liegt +unverändert als `openai_api_key` in der Scanner-Tabelle `settings` - dort, wo er +schon immer lag. Nichts musste umziehen. Ersatzweise gilt `OPENAI_API_KEY` aus +`server/.env`. + +* **Anzeige nur mit Ende.** Die Oberfläche zeigt `sk-…` und die letzten vier + Zeichen, dazu die Quelle (*hier hinterlegt* oder *server/.env*). Mehr gibt der + Server nie heraus, auch nicht an Administratoren. Bei Schlüsseln unter zwölf + Zeichen steht nur *ja*. +* **Vor dem Speichern geprüft.** Ein neuer Schlüssel wird erst gegen + `GET https://api.openai.com/v1/models` ausprobiert. Lehnt OpenAI ab, bleibt der + alte gültig, und die Meldung von OpenAI steht im Fehlertext. Der Abruf kostet + nichts. +* **Verwerfen** leert den hinterlegten Wert. Danach gilt wieder die `.env` - + oder, wenn dort nichts steht, gibt es keinen Schlüssel mehr. +* Der Schlüssel liegt **unverschlüsselt** in der Scanner-Datenbank, wie bisher. + Ein Dump von `perinco_scanner` enthält ihn also. + +Im Reiter *Scanner* gibt es kein Schlüsselfeld mehr. `POST /api/scanner/settings` +nimmt `openai_api_key` aus Kompatibilität weiter an. + +## Modelle + +Das Dropdown füllt sich **live von OpenAI**: alle Modelle, die der Schlüssel +nutzen darf, gefiltert auf Textmodelle (`gpt-*`, `o1`/`o3`/`o4…`, `chatgpt-*`, +ohne Audio, Bild, Embedding, Realtime, TTS, Suche, Moderation). Die aktuell +eingestellten Modelle stehen immer mit drin, die Vorgabe ist markiert. + +Ist die Liste nicht abrufbar (kein Schlüssel, OpenAI nicht erreichbar), zeigt +das Dropdown eine feste Auswahl, und die Seite sagt, warum. + +Die Wahl gilt ab dem nächsten Aufruf - es gibt keinen Zwischenspeicher. + +### Reasoning- und klassische Modelle + +Die beiden Modellfamilien nehmen unterschiedliche Parameter. Damit ein Wechsel +im Dropdown keinen `400` von OpenAI auslöst, entscheidet `isReasoningModel()` +(Namen `o1…`, `o3…`, `gpt-5…`) je Aufruf: + +| | Reasoning (`o*`, `gpt-5*`) | klassisch (`gpt-4o*`, `gpt-4.1*`) | +| --- | --- | --- | +| Scanner-Bewertung | `reasoning_effort: low` | `temperature: 0.1` | +| Abgleich „bereits beworben" | `reasoning_effort: low` | `temperature: 0` | +| Erweiterte Suche | `max_completion_tokens` | `max_completion_tokens` | + +`max_completion_tokens` verstehen beide Familien, das alte `max_tokens` die +Reasoning-Modelle nicht. + +## Endpunkte + +Alle unter `/api/ai`, nur für Administratoren. + +| Methode | Pfad | Zweck | +| --- | --- | --- | +| GET | `/settings` | Schlüsselzustand, Modell je Zweck, Auswahlliste | +| PUT | `/key` | `{ key }` - prüfen, dann speichern | +| DELETE | `/key` | hinterlegten Schlüssel verwerfen | +| PUT | `/models` | `{ matching?, applied?, search? }` - Namen geprüft gegen `^[A-Za-z0-9][A-Za-z0-9._:-]{0,99}$` | + +## Dateien + +| Datei | Aufgabe | +| --- | --- | +| `server/src/ai.js` | Schlüssel, Modellwahl, Modellliste, Aufruf der Suche | +| `server/src/routes/ai.js` | die vier Endpunkte | +| `src/components/settings/AiSettings.tsx` | Reiter *KI* | +| `server/test/ai.test.mjs` | Modellnamen und Reasoning-Erkennung | diff --git a/docs/README.md b/docs/README.md index bb5d0a0..343081e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,69 +1,70 @@ -# Dokumentation perinco CRM - -Technische Dokumentation mit Funktionszeichnungen. Die Diagramme sind Mermaid und -werden von Gitea direkt gerendert. - -**Neu hier?** Wer die Anwendung *benutzen* will, fängt bei -[07 Anleitung für Benutzer](07-anleitung-benutzer.md) an. Wer daran *entwickeln* -will, bei [08 Anleitung für Entwickler](08-anleitung-entwickler.md). Beide setzen -keine Vorkenntnisse voraus. - -| Kapitel | Inhalt | -| --- | --- | -| [01 Architektur](01-architektur.md) | Topologie, Prozesse, Ports, Anfrageweg, Rollen | -| [02 Datenmodell](02-datenmodell.md) | Tabellen beider Datenbanken als ER-Diagramme | -| [03 Projekt Scanner](03-scanner.md) | Suchlauf von der Börse bis zum Treffer, Rückbau der alten App | -| [04 Diktat](04-diktat.md) | Spracherkennung im Browser, Modell-Lebenszyklus | -| [05 Frontend](05-frontend.md) | Ansichten, Menü, Komponentenkarte, Zustand | -| [06 Betrieb](06-betrieb.md) | Deployment, Umgebungsvariablen, Dienste, Störungssuche | -| [07 Anleitung für Benutzer](07-anleitung-benutzer.md) | Bedienung aller Bereiche, Schritt für Schritt | -| [08 Anleitung für Entwickler](08-anleitung-entwickler.md) | Einrichten, erweitern, bekannte Fallen | -| [09 Quellcode-Referenz](09-quellcode.md) | jede Datei, ihre Exporte und Zusagen | -| [10 Glossar](10-glossar.md) | Agent, Match, Lead, Opportunity, Status- und Portalwerte | -| [11 Postfachanbindung](11-postfach.md) | crm@perinco.de über Microsoft Graph, Kontakte aus Mails | -| [12 Globale Suche](12-suche.md) | Volltext und erweiterte Suche im Kopf der Anwendung | -| [13 Anmeldung über Microsoft](13-anmeldung-sso.md) | SSO mit Entra, Zuordnung der Konten, Einrichtung | - -Die Designentscheidungen und die Messwerte zur Spracherkennung stehen im -[README des Projekts](../README.md). - -## Das Ganze in einem Bild - -```mermaid -flowchart TB - subgraph Browser - SPA["React-SPA
Vite-Build"] - WSP["Whisper im Web Worker
WebGPU / WASM"] - end - - subgraph Server["Server 212.227.135.41"] - AP["Apache
:443"] - API["Express-Backend
127.0.0.1:5006"] - SCH["Scanner-Scheduler
node-cron"] - MSCH["Mail-Scheduler
node-cron"] - PW["Playwright
Chromium"] - DB1[("MariaDB
perinco_CRM")] - DB2[("MariaDB
perinco_scanner")] - end - - OAI["OpenAI
gpt-4o-mini"] - BOERSE["Projektbörsen
freelancermap, hays, ..."] - GRAPH["Microsoft Graph
crm@perinco.de"] - - SPA -->|"HTTPS /api"| AP - AP --> API - API --> DB1 - API --> DB2 - SCH --> PW - PW --> BOERSE - SCH --> OAI - SCH --> DB2 - API -.-> SCH - API -.-> MSCH - MSCH -->|"Delta Query, nur lesend"| GRAPH - MSCH --> DB1 - SPA -.->|"Audio bleibt im Browser"| WSP -``` - -Die ursprüngliche Scanner-App unter `scanner.perinco.de` ist am 09.09.2026 -zurückgebaut worden; das CRM ist seither die einzige Instanz. +# Dokumentation perinco CRM + +Technische Dokumentation mit Funktionszeichnungen. Die Diagramme sind Mermaid und +werden von Gitea direkt gerendert. + +**Neu hier?** Wer die Anwendung *benutzen* will, fängt bei +[07 Anleitung für Benutzer](07-anleitung-benutzer.md) an. Wer daran *entwickeln* +will, bei [08 Anleitung für Entwickler](08-anleitung-entwickler.md). Beide setzen +keine Vorkenntnisse voraus. + +| Kapitel | Inhalt | +| --- | --- | +| [01 Architektur](01-architektur.md) | Topologie, Prozesse, Ports, Anfrageweg, Rollen | +| [02 Datenmodell](02-datenmodell.md) | Tabellen beider Datenbanken als ER-Diagramme | +| [03 Projekt Scanner](03-scanner.md) | Suchlauf von der Börse bis zum Treffer, Rückbau der alten App | +| [04 Diktat](04-diktat.md) | Spracherkennung im Browser, Modell-Lebenszyklus | +| [05 Frontend](05-frontend.md) | Ansichten, Menü, Komponentenkarte, Zustand | +| [06 Betrieb](06-betrieb.md) | Deployment, Umgebungsvariablen, Dienste, Störungssuche | +| [07 Anleitung für Benutzer](07-anleitung-benutzer.md) | Bedienung aller Bereiche, Schritt für Schritt | +| [08 Anleitung für Entwickler](08-anleitung-entwickler.md) | Einrichten, erweitern, bekannte Fallen | +| [09 Quellcode-Referenz](09-quellcode.md) | jede Datei, ihre Exporte und Zusagen | +| [10 Glossar](10-glossar.md) | Agent, Match, Lead, Opportunity, Status- und Portalwerte | +| [11 Postfachanbindung](11-postfach.md) | crm@perinco.de über Microsoft Graph, Kontakte aus Mails | +| [12 Globale Suche](12-suche.md) | Volltext und erweiterte Suche im Kopf der Anwendung | +| [13 Anmeldung über Microsoft](13-anmeldung-sso.md) | SSO mit Entra, Zuordnung der Konten, Einrichtung | +| [14 KI](14-ki.md) | OpenAI-Schlüssel und Modellwahl je Einsatzzweck | + +Die Designentscheidungen und die Messwerte zur Spracherkennung stehen im +[README des Projekts](../README.md). + +## Das Ganze in einem Bild + +```mermaid +flowchart TB + subgraph Browser + SPA["React-SPA
Vite-Build"] + WSP["Whisper im Web Worker
WebGPU / WASM"] + end + + subgraph Server["Server 212.227.135.41"] + AP["Apache
:443"] + API["Express-Backend
127.0.0.1:5006"] + SCH["Scanner-Scheduler
node-cron"] + MSCH["Mail-Scheduler
node-cron"] + PW["Playwright
Chromium"] + DB1[("MariaDB
perinco_CRM")] + DB2[("MariaDB
perinco_scanner")] + end + + OAI["OpenAI
gpt-4o-mini"] + BOERSE["Projektbörsen
freelancermap, hays, ..."] + GRAPH["Microsoft Graph
crm@perinco.de"] + + SPA -->|"HTTPS /api"| AP + AP --> API + API --> DB1 + API --> DB2 + SCH --> PW + PW --> BOERSE + SCH --> OAI + SCH --> DB2 + API -.-> SCH + API -.-> MSCH + MSCH -->|"Delta Query, nur lesend"| GRAPH + MSCH --> DB1 + SPA -.->|"Audio bleibt im Browser"| WSP +``` + +Die ursprüngliche Scanner-App unter `scanner.perinco.de` ist am 09.09.2026 +zurückgebaut worden; das CRM ist seither die einzige Instanz. diff --git a/docs/bilder/einstellungen-ki.png b/docs/bilder/einstellungen-ki.png new file mode 100644 index 0000000000000000000000000000000000000000..5278e95a5122d4d574f496f13f9964500b31681f GIT binary patch literal 174565 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 literal 0 HcmV?d00001 diff --git a/server/.env.example b/server/.env.example index 40590ef..339a85d 100644 --- a/server/.env.example +++ b/server/.env.example @@ -92,7 +92,9 @@ SCANNER_SCHEDULER=true # 0 = sofort loslegen. SCANNER_SCHEDULER_OFFSET=0 -# Fallback fuer den OpenAI-Key; bevorzugt wird der Wert aus den Einstellungen. +# Fallback fuer den OpenAI-Key; bevorzugt wird der Wert aus Einstellungen > KI. +# Dort wird auch das Modell je Einsatzzweck gewaehlt. +# OPENAI_MODEL setzt nur die Vorgabe der erweiterten Suche. # OPENAI_API_KEY= # --------------------------------------------------------------------------- diff --git a/server/package.json b/server/package.json index c235604..ad1dd14 100644 --- a/server/package.json +++ b/server/package.json @@ -12,7 +12,7 @@ "start": "node src/server.js", "dev": "node --watch src/server.js", "migrate": "node src/migrate.js", - "test": "node test/mail.test.mjs && node test/acquisition.test.mjs && node test/userFields.test.mjs && node test/linkedinPhoto.test.mjs && node test/sessionUser.test.mjs && node test/sso.test.mjs && node test/msSecret.test.mjs" + "test": "node test/mail.test.mjs && node test/acquisition.test.mjs && node test/userFields.test.mjs && node test/linkedinPhoto.test.mjs && node test/sessionUser.test.mjs && node test/sso.test.mjs && node test/msSecret.test.mjs && node test/ai.test.mjs" }, "dependencies": { "bcryptjs": "^2.4.3", diff --git a/server/src/ai.js b/server/src/ai.js index b086e28..7064a50 100644 --- a/server/src/ai.js +++ b/server/src/ai.js @@ -1,13 +1,22 @@ import Setting from './scanner/models/Setting.js'; +import { getSettings, setSetting } from './settings.js'; /* - * Anbindung an OpenAI fuer das CRM (bisher nutzte nur der Scanner ein Modell). + * Anbindung an OpenAI - Schluessel, Modellwahl und der eine Aufruf, den das + * CRM selbst macht (erweiterte Suche). * - * Der Schluessel wird NICHT zum zweiten Mal gepflegt: es ist derselbe, den der - * Scanner benutzt - Einstellungen -> Scanner, gespeichert als `openai_api_key` - * in der Scanner-Tabelle `settings`. Ein zweiter Schluessel an zweiter Stelle - * waere eine Quelle fuer den Fall "die eine Funktion geht, die andere nicht, - * und keiner weiss warum". + * Gepflegt wird alles in Einstellungen -> KI (nur Administratoren): + * + * Schluessel Es gibt genau einen. Er liegt weiterhin als `openai_api_key` in + * der Scanner-Tabelle `settings`, wo er schon immer lag - so + * muss nichts umziehen, und Scanner wie CRM lesen dieselbe + * Stelle. Ersatzweise gilt OPENAI_API_KEY aus der .env. + * Ausgeliefert werden nur die letzten vier Zeichen. + * + * Modelle Je Einsatzzweck eins (AI_PURPOSES), gespeichert in + * crm_settings als `ai_model_`. Ohne Eintrag gilt die + * Vorgabe - das ist genau das Modell, das vor der Einstellung + * fest im Code stand. * * Bewusst ohne das `openai`-Paket: gebraucht wird ein einziger Aufruf, und * `fetch` ist in Node eingebaut. Der Scanner behaelt sein SDK - dort haengt @@ -16,11 +25,39 @@ import Setting from './scanner/models/Setting.js'; * Der Schluessel bleibt auf dem Server. Der Browser spricht nie mit OpenAI. */ -const ENDPOINT = 'https://api.openai.com/v1/chat/completions'; +const API_BASE = 'https://api.openai.com/v1'; const TIMEOUT_MS = 120_000; +const KEY_SETTING = 'openai_api_key'; -/** Dasselbe Modell wie im Scanner - was dort ausreicht, reicht hier auch. */ -export const AI_MODEL = process.env.OPENAI_MODEL || 'gpt-4o-mini'; +/** + * Einsatzzwecke mit ihrer Vorgabe. Reihenfolge = Reihenfolge in der Oberflaeche. + * Die Vorgabe der Suche laesst sich weiter ueber OPENAI_MODEL setzen. + */ +export const AI_PURPOSES = { + matching: { + label: 'Scanner: Bewertung Lebenslauf gegen Projekt', + fallback: 'gpt-4o-mini', + }, + applied: { + label: 'Scanner: Abgleich „bereits beworben“', + fallback: 'gpt-5.6-luna', + }, + search: { + label: 'Erweiterte Suche', + fallback: process.env.OPENAI_MODEL || 'gpt-4o-mini', + }, +}; + +/** + * Auswahl, falls OpenAI die Modellliste nicht liefert (kein Schluessel, + * nicht erreichbar). Die aktuell eingestellten Modelle kommen immer dazu. + */ +const FALLBACK_MODELS = ['gpt-5.6-luna', 'gpt-5', 'gpt-5-mini', 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4o', 'gpt-4o-mini']; + +const settingKey = (purpose) => `ai_model_${purpose}`; + +/** Modellnamen von OpenAI: Buchstaben, Ziffern, Punkt, Bindestrich, Doppelpunkt. */ +const MODEL_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,99}$/; class AiError extends Error { constructor(message, status = 502) { @@ -29,16 +66,175 @@ class AiError extends Error { } } -/** Der Schluessel des Scanners, ersatzweise aus der Umgebung. */ +/* --------------------------------------------------------------------------- + * Schluessel + * ------------------------------------------------------------------------- */ + +const envKey = () => (process.env.OPENAI_API_KEY || '').trim(); + +/** Der Schluessel samt Herkunft ('db', 'env' oder null). */ +async function effectiveKey() { + const fromDb = ((await Setting.getVal(KEY_SETTING)) || '').trim(); + if (fromDb) return { value: fromDb, source: 'db' }; + const fromEnv = envKey(); + return fromEnv ? { value: fromEnv, source: 'env' } : { value: '', source: null }; +} + +/** Der gueltige Schluessel - Datenbank vor .env. */ export async function aiKey() { - const fromDb = await Setting.getVal('openai_api_key'); - return (fromDb || process.env.OPENAI_API_KEY || '').trim(); + return (await effectiveKey()).value; } export async function aiConfigured() { return Boolean(await aiKey()); } +/** Zustand fuer die Oberflaeche: nur die letzten vier Zeichen, nie mehr. */ +export async function keyStatus() { + const { value, source } = await effectiveKey(); + return { + configured: Boolean(value), + source, + last4: value.length >= 12 ? value.slice(-4) : null, + env_fallback: Boolean(envKey()), + }; +} + +/** Speichert einen neuen Schluessel. Pruefen muss der Aufrufer vorher (verifyKey). */ +export async function saveKey(key) { + await Setting.setVal(KEY_SETTING, key); + return keyStatus(); +} + +/** Verwirft den hinterlegten Schluessel - ab dann gilt wieder die .env. */ +export async function clearKey() { + await Setting.setVal(KEY_SETTING, ''); + return keyStatus(); +} + +async function openAiGet(path, key) { + let response; + try { + response = await fetch(`${API_BASE}${path}`, { + headers: { Authorization: `Bearer ${key}` }, + signal: AbortSignal.timeout(20_000), + }); + } catch (err) { + return { ok: false, error: `OpenAI ist nicht erreichbar: ${err.message}` }; + } + const data = await response.json().catch(() => null); + if (!response.ok) { + return { ok: false, error: data?.error?.message || `HTTP ${response.status}` }; + } + return { ok: true, data }; +} + +/** + * Probiert einen Schluessel aus, bevor er gespeichert wird. Die Modellliste + * abzurufen kostet nichts und scheitert bei falschem Schluessel mit 401. + */ +export async function verifyKey(candidate) { + const result = await openAiGet('/models', candidate); + return result.ok ? { ok: true } : { ok: false, error: result.error }; +} + +/* --------------------------------------------------------------------------- + * Modelle + * ------------------------------------------------------------------------- */ + +export function isValidModel(value) { + return MODEL_PATTERN.test(String(value ?? '')); +} + +/** + * Reasoning-Modelle (o1, o3, o4-mini, gpt-5 ...) nehmen kein `temperature`, + * dafuer `reasoning_effort`. Wer in den Einstellungen umstellt, soll keinen + * 400er von OpenAI bekommen - die Aufrufer fragen deshalb hier nach. + */ +export function isReasoningModel(model) { + return /^(o\d|gpt-5)/i.test(String(model ?? '')); +} + +/** Eingestelltes Modell je Zweck, sonst die Vorgabe. */ +export async function modelFor(purpose) { + const entry = AI_PURPOSES[purpose]; + if (!entry) throw new Error(`Unbekannter KI-Zweck: ${purpose}`); + let stored = ''; + try { + const values = await getSettings({ [settingKey(purpose)]: '' }); + stored = values[settingKey(purpose)] || ''; + } catch (err) { + console.warn('[KI] Modellwahl nicht lesbar, nutze Vorgabe:', err.message); + } + return isValidModel(stored) ? stored : entry.fallback; +} + +/** Alle Zwecke mit aktuellem Modell und Vorgabe. */ +export async function modelSettings() { + const result = {}; + for (const [purpose, entry] of Object.entries(AI_PURPOSES)) { + result[purpose] = { label: entry.label, model: await modelFor(purpose), fallback: entry.fallback }; + } + return result; +} + +/** Speichert die Modellwahl; nur bekannte Zwecke, nur plausible Namen. */ +export async function saveModels(input) { + for (const purpose of Object.keys(AI_PURPOSES)) { + if (input?.[purpose] === undefined) continue; + const value = String(input[purpose]).trim(); + if (!isValidModel(value)) { + throw new AiError(`Ungültiger Modellname: ${value || '(leer)'}`, 400); + } + await setSetting(settingKey(purpose), value); + } + return modelSettings(); +} + +/** + * Textmodelle, die sich fuer Chat Completions eignen. OpenAI liefert auch + * Audio-, Bild-, Embedding- und Moderationsmodelle - die gehoeren nicht in die + * Auswahl. + */ +const EXCLUDED = /(audio|realtime|tts|transcribe|whisper|dall-e|image|embedding|moderation|search|instruct|codex|computer-use|babbage|davinci)/i; +const CHAT_MODEL = /^(gpt-|o\d|chatgpt-)/i; + +/** + * Auswahl fuer das Dropdown. Ohne Schluessel oder bei Fehler die feste + * Liste - mit Hinweis, damit die Oberflaeche es sagen kann. + */ +export async function availableModels() { + const current = Object.values(await modelSettings()).map((entry) => entry.model); + const key = await aiKey(); + + let models = []; + let source = 'fallback'; + let error = null; + + if (key) { + const result = await openAiGet('/models', key); + if (result.ok && Array.isArray(result.data?.data)) { + models = result.data.data + .map((entry) => String(entry.id)) + .filter((id) => CHAT_MODEL.test(id) && !EXCLUDED.test(id)); + source = 'openai'; + } else { + error = result.error || 'Modellliste nicht lesbar.'; + } + } + if (models.length === 0) models = [...FALLBACK_MODELS]; + + return { + models: [...new Set([...models, ...current])].sort((a, b) => a.localeCompare(b, 'en', { numeric: true })), + source, + error, + }; +} + +/* --------------------------------------------------------------------------- + * Aufruf + * ------------------------------------------------------------------------- */ + /** * Ein Aufruf an das Modell, Antwort als JSON. * @@ -46,32 +242,32 @@ export async function aiConfigured() { * @param {string} options.system * @param {string} options.user * @param {number} [options.maxTokens] + * @param {string} [options.model] - sonst das Modell der Suche */ -export async function askModelJson({ system, user, maxTokens }) { +export async function askModelJson({ system, user, maxTokens, model }) { const key = await aiKey(); if (!key) { - throw new AiError( - 'Es ist kein OpenAI-Schlüssel hinterlegt (Einstellungen → Scanner).', - 503 - ); + throw new AiError('Es ist kein OpenAI-Schlüssel hinterlegt (Einstellungen → KI).', 503); } const body = { - model: AI_MODEL, + model: model || (await modelFor('search')), messages: [ ...(system ? [{ role: 'system', content: system }] : []), { role: 'user', content: user }, ], response_format: { type: 'json_object' }, }; - if (maxTokens) body.max_tokens = maxTokens; + // max_completion_tokens verstehen alle aktuellen Modelle, max_tokens die + // Reasoning-Modelle nicht. + if (maxTokens) body.max_completion_tokens = maxTokens; const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), TIMEOUT_MS); let response; try { - response = await fetch(ENDPOINT, { + response = await fetch(`${API_BASE}/chat/completions`, { method: 'POST', headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' }, body: JSON.stringify(body), diff --git a/server/src/routes/ai.js b/server/src/routes/ai.js new file mode 100644 index 0000000..6b9999a --- /dev/null +++ b/server/src/routes/ai.js @@ -0,0 +1,77 @@ +import express from 'express'; +import { requireAuth, requireAdmin } from '../middleware/auth.js'; +import { + availableModels, + clearKey, + keyStatus, + modelSettings, + saveKey, + saveModels, + verifyKey, +} from '../ai.js'; + +/* + * Einstellungen -> KI. Nur Administratoren. + * + * Der Schluessel geht nur hinein; heraus kommen seine letzten vier Zeichen, + * damit man erkennt, welcher hinterlegt ist. + */ + +const router = express.Router(); +router.use(requireAuth, requireAdmin); + +// GET /api/ai/settings +router.get('/settings', async (req, res, next) => { + try { + res.json({ + key: await keyStatus(), + models: await modelSettings(), + available: await availableModels(), + }); + } catch (err) { + next(err); + } +}); + +// PUT /api/ai/key { key } +router.put('/key', async (req, res, next) => { + const key = String(req.body?.key ?? '').trim(); + if (!key) return res.status(400).json({ error: 'Kein Schlüssel übergeben.' }); + if (key.length > 500 || /\s/.test(key)) { + return res.status(400).json({ error: 'Das sieht nicht nach einem OpenAI-Schlüssel aus.' }); + } + + try { + // Erst bei OpenAI ausprobieren, dann speichern: ein vertippter Schluessel + // legt sonst still Scanner und Suche lahm. + const check = await verifyKey(key); + if (!check.ok) { + return res.status(400).json({ error: `OpenAI hat diesen Schlüssel abgelehnt: ${check.error}` }); + } + const status = await saveKey(key); + res.json({ ok: true, key: status, available: await availableModels() }); + } catch (err) { + next(err); + } +}); + +// DELETE /api/ai/key - hinterlegten Schluessel verwerfen, .env gilt wieder +router.delete('/key', async (req, res, next) => { + try { + res.json({ ok: true, key: await clearKey(), available: await availableModels() }); + } catch (err) { + next(err); + } +}); + +// PUT /api/ai/models { matching?, applied?, search? } +router.put('/models', async (req, res, next) => { + try { + res.json({ ok: true, models: await saveModels(req.body) }); + } catch (err) { + if (err?.status) return res.status(err.status).json({ error: err.message }); + next(err); + } +}); + +export default router; diff --git a/server/src/routes/search.js b/server/src/routes/search.js index eeb690e..42ebb29 100644 --- a/server/src/routes/search.js +++ b/server/src/routes/search.js @@ -1,7 +1,7 @@ import express from 'express'; import { pool } from '../db.js'; import { requireAuth } from '../middleware/auth.js'; -import { askModelJson, aiConfigured, AI_MODEL } from '../ai.js'; +import { askModelJson, aiConfigured, modelFor } from '../ai.js'; import { fetchIconContacts } from './iconCrm.js'; const router = express.Router(); @@ -160,7 +160,7 @@ router.post('/ai', async (req, res, next) => { if (!question) return res.status(400).json({ error: 'Keine Frage übergeben.' }); if (!(await aiConfigured())) { return res.status(503).json({ - error: 'Es ist kein OpenAI-Schlüssel hinterlegt (Einstellungen → Scanner).', + error: 'Es ist kein OpenAI-Schlüssel hinterlegt (Einstellungen → KI).', }); } @@ -202,7 +202,9 @@ router.post('/ai', async (req, res, next) => { (list) => list.length >= AI_LIMIT ); + const model = await modelFor('search'); const result = await askModelJson({ + model, system: AI_SYSTEM, user: `Frage: ${question}\n\nBestand:\n${JSON.stringify({ leads: leads.map((row) => ({ ...row, mail_pool: Boolean(row.mail_pool) })), @@ -225,7 +227,7 @@ router.post('/ai', async (req, res, next) => { res.json({ answer: String(result?.answer ?? '').trim(), refs: Array.isArray(result?.refs) ? result.refs.slice(0, 30) : [], - model: AI_MODEL, + model, truncated, }); } catch (err) { diff --git a/server/src/scanner/services/appliedCheck.js b/server/src/scanner/services/appliedCheck.js index 4e62a4e..a6c9067 100644 --- a/server/src/scanner/services/appliedCheck.js +++ b/server/src/scanner/services/appliedCheck.js @@ -1,6 +1,7 @@ import { OpenAI } from 'openai'; import { pool } from '../../db.js'; import Setting from '../models/Setting.js'; +import { aiKey, isReasoningModel, modelFor } from '../../ai.js'; /* * Abgleich "bereits beworben?". @@ -19,7 +20,6 @@ import Setting from '../models/Setting.js'; * applied_check_days Zeitraum in Tagen, Vorgabe 14 */ -export const APPLIED_CHECK_MODEL = 'gpt-5.6-luna'; export const APPLIED_CHECK_DEFAULT_DAYS = 14; const MAX_DAYS = 365; @@ -101,8 +101,10 @@ const toRef = (candidate, reason) => ({ }); async function askModel(project, candidates) { - const apiKey = (await Setting.getVal('openai_api_key')) || process.env.OPENAI_API_KEY; + const apiKey = await aiKey(); if (!apiKey) throw new Error('OpenAI API Key is not configured.'); + // Modell aus Einstellungen -> KI, Vorgabe gpt-5.6-luna. + const model = await modelFor('applied'); const openai = new OpenAI({ apiKey }); @@ -138,13 +140,13 @@ ${JSON.stringify( )}`; const response = await openai.chat.completions.create({ - model: APPLIED_CHECK_MODEL, + model, messages: [ { role: 'system', content: system }, { role: 'user', content: user }, ], response_format: { type: 'json_object' }, - reasoning_effort: 'low', + ...(isReasoningModel(model) ? { reasoning_effort: 'low' } : { temperature: 0 }), }); const parsed = JSON.parse(response.choices[0]?.message?.content || '{}'); diff --git a/server/src/scanner/services/matchingEngine.js b/server/src/scanner/services/matchingEngine.js index 94bf7f8..9179aa1 100644 --- a/server/src/scanner/services/matchingEngine.js +++ b/server/src/scanner/services/matchingEngine.js @@ -1,5 +1,5 @@ import { OpenAI } from 'openai'; -import Setting from '../models/Setting.js'; +import { aiKey, isReasoningModel, modelFor } from '../../ai.js'; /** * Evaluates the match between an agent's CV and a scraped project description using OpenAI. @@ -16,11 +16,12 @@ export const evaluateMatch = async (cvText, projectDescription) => { }; } - // Fetch API key from DB, fallback to environment variable - const apiKey = await Setting.getVal('openai_api_key') || process.env.OPENAI_API_KEY; + // Schluessel und Modell kommen aus Einstellungen -> KI. + const apiKey = await aiKey(); if (!apiKey) { throw new Error('OpenAI API Key is not configured. Please set it in Settings.'); } + const model = await modelFor('matching'); const openai = new OpenAI({ apiKey }); @@ -55,13 +56,14 @@ ${projectDescription}`; try { const response = await openai.chat.completions.create({ - model: 'gpt-4o-mini', + model, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userContent } ], response_format: { type: 'json_object' }, - temperature: 0.1 // Low temperature for more deterministic analysis + // Reasoning models reject temperature; low temperature keeps classic models deterministic. + ...(isReasoningModel(model) ? { reasoning_effort: 'low' } : { temperature: 0.1 }) }); const rawContent = response.choices[0].message.content.trim(); diff --git a/server/src/server.js b/server/src/server.js index 745cdb4..70ad5fa 100644 --- a/server/src/server.js +++ b/server/src/server.js @@ -16,6 +16,7 @@ import mailRoutes from './routes/mail.js'; import integrationRoutes from './routes/integrations.js'; import iconCrmRoutes from './routes/iconCrm.js'; import searchRoutes from './routes/search.js'; +import aiRoutes from './routes/ai.js'; import { requireAuth } from './middleware/auth.js'; import { initScannerDatabase } from './scanner/models/index.js'; import { startScheduler } from './scanner/services/scheduler.js'; @@ -61,6 +62,8 @@ app.use('/api/users', userRoutes); app.use('/api/leads', leadRoutes); // Globale Suche (Volltext) und die erweiterte Suche mit dem Modell des Scanners. app.use('/api/search', searchRoutes); +// OpenAI-Schluessel und Modellwahl (Einstellungen -> KI, nur admin). +app.use('/api/ai', aiRoutes); app.use('/api/connections', connectionRoutes); app.use('/api/events', eventRoutes); app.use('/api/opportunities', opportunityRoutes); diff --git a/server/test/ai.test.mjs b/server/test/ai.test.mjs new file mode 100644 index 0000000..912d0b3 --- /dev/null +++ b/server/test/ai.test.mjs @@ -0,0 +1,43 @@ +/* + * Prueft die Modellwahl, soweit es ohne Datenbank und OpenAI geht: welche + * Namen angenommen werden und welche Modelle als Reasoning-Modell gelten + * (die bekommen reasoning_effort statt temperature). + */ +const { AI_PURPOSES, isReasoningModel, isValidModel } = await import('../src/ai.js'); + +let failures = 0; + +function check(name, condition) { + if (condition) { + console.log(` ok ${name}`); + } else { + failures += 1; + console.log(` FAIL ${name}`); + } +} + +console.log('KI-Einstellungen'); + +check('Vorgabe Bewertung ist gpt-4o-mini', AI_PURPOSES.matching.fallback === 'gpt-4o-mini'); +check('Vorgabe Abgleich ist gpt-5.6-luna', AI_PURPOSES.applied.fallback === 'gpt-5.6-luna'); + +for (const name of ['gpt-4o-mini', 'gpt-5.6-luna', 'o4-mini', 'gpt-4o-2024-08-06', 'ft:gpt-4o-mini:perinco:x:1']) { + check(`gueltig: ${name}`, isValidModel(name)); +} +for (const name of ['', ' gpt-4o', 'gpt 4o', 'gpt-4o;drop', 'x'.repeat(101), null]) { + check(`ungueltig: ${JSON.stringify(name)?.slice(0, 20)}`, !isValidModel(name)); +} + +for (const name of ['o1', 'o3-mini', 'o4-mini', 'gpt-5', 'gpt-5.6-luna']) { + check(`reasoning: ${name}`, isReasoningModel(name)); +} +for (const name of ['gpt-4o-mini', 'gpt-4.1', 'chatgpt-4o-latest']) { + check(`klassisch: ${name}`, !isReasoningModel(name)); +} + +if (failures) { + console.log(`\n${failures} Pruefung(en) fehlgeschlagen.`); + process.exit(1); +} +console.log('\nAlles gruen.'); +process.exit(0); diff --git a/src/App.tsx b/src/App.tsx index 047ba7c..d0a8a65 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -181,7 +181,7 @@ const App: React.FC = () => { Unpassend: 'Projekt Scanner - als „passt nicht" markierte Treffer', Suchagenten: 'Projekt Scanner - Beraterprofile mit CV und Suchbegriffen', 'Börsen-Konten': 'Projekt Scanner - Verbindungen zu den Jobbörsen', - Einstellungen: 'Konto, Diktat, Benutzer, Postfach und Scanner', + Einstellungen: 'Konto, Diktat, Benutzer, Postfach, Scanner und KI', }; const subtitle = diff --git a/src/components/settings/AiSettings.tsx b/src/components/settings/AiSettings.tsx new file mode 100644 index 0000000..272ab4d --- /dev/null +++ b/src/components/settings/AiSettings.tsx @@ -0,0 +1,287 @@ +import React, { useEffect, useState } from 'react'; +import { + aiApi, + type AiAvailableModels, + type AiKeyStatus, + type AiPurpose, + type AiSettings as AiSettingsData, +} from '../../lib/api'; +import { inputClass, labelClass } from '../leads/leadUi'; +import { useToast } from '../Toast'; + +/* + * KI - Adminsicht: OpenAI-Schlüssel und das Modell je Einsatzzweck. + * + * Der Schlüssel geht nur hinein. Angezeigt werden seine letzten vier Zeichen, + * damit man erkennt, welcher hinterlegt ist - mehr gibt der Server nicht her. + * Es gibt genau einen Schlüssel für Scanner und CRM. + */ + +const Fact: React.FC<{ label: string; value: React.ReactNode }> = ({ label, value }) => ( +
+
{label}
+
{value}
+
+); + +const KeySection: React.FC<{ + keyStatus: AiKeyStatus; + onChange: (key: AiKeyStatus, available: AiAvailableModels) => void; +}> = ({ keyStatus, onChange }) => { + const { addToast } = useToast(); + const [value, setValue] = useState(''); + const [isSaving, setIsSaving] = useState(false); + const [isClearing, setIsClearing] = useState(false); + + const handleSubmit = async (event: React.FormEvent) => { + event.preventDefault(); + if (!value.trim()) return; + setIsSaving(true); + try { + const result = await aiApi.saveKey(value.trim()); + onChange(result.key, result.available); + setValue(''); + addToast('Schlüssel gespeichert - OpenAI hat ihn akzeptiert.', 'success'); + } catch (err) { + addToast(err instanceof Error ? err.message : 'Speichern fehlgeschlagen.', 'error'); + } finally { + setIsSaving(false); + } + }; + + const handleClear = async () => { + setIsClearing(true); + try { + const result = await aiApi.clearKey(); + onChange(result.key, result.available); + addToast( + result.key.configured + ? 'Hinterlegter Schlüssel verworfen - es gilt wieder der Wert aus server/.env.' + : 'Hinterlegter Schlüssel verworfen.', + 'success' + ); + } catch (err) { + addToast(err instanceof Error ? err.message : 'Verwerfen fehlgeschlagen.', 'error'); + } finally { + setIsClearing(false); + } + }; + + return ( +
+

OpenAI-Schlüssel

+

+ Ein Schlüssel für alles: Scanner-Bewertung, Abgleich „bereits beworben“ und erweiterte Suche. + Angezeigt wird nur das Ende. +

+ +
+ + {keyStatus.last4 ? `sk-…${keyStatus.last4}` : 'ja'} + + ) : ( + kein Schlüssel + ) + } + /> + +
+ + {!keyStatus.configured && ( +

+ Ohne Schlüssel bewertet der Scanner keine Projekte und die erweiterte Suche bleibt aus. +

+ )} + +
+
+ + setValue(event.target.value)} + placeholder="sk-proj-..." + className={inputClass} + /> +

+ Beim Speichern fragt das CRM testweise bei OpenAI an - ein vertippter Schlüssel wird gar + nicht erst übernommen. Der alte bleibt bis dahin gültig. +

+
+ +
+ + + {keyStatus.source === 'db' && ( + + )} +
+
+
+ ); +}; + +const PURPOSE_ORDER: AiPurpose[] = ['matching', 'applied', 'search']; + +const ModelSection: React.FC<{ + models: AiSettingsData['models']; + available: AiAvailableModels; + onChange: (models: AiSettingsData['models']) => void; +}> = ({ models, available, onChange }) => { + const { addToast } = useToast(); + const [draft, setDraft] = useState>(() => ({ + matching: models.matching.model, + applied: models.applied.model, + search: models.search.model, + })); + const [isSaving, setIsSaving] = useState(false); + + const changed = PURPOSE_ORDER.filter((purpose) => draft[purpose] !== models[purpose].model); + + const handleSubmit = async (event: React.FormEvent) => { + event.preventDefault(); + if (changed.length === 0) return; + setIsSaving(true); + try { + const payload: Partial> = {}; + for (const purpose of changed) payload[purpose] = draft[purpose]; + const result = await aiApi.saveModels(payload); + onChange(result.models); + addToast('Modellwahl gespeichert. Gilt ab dem nächsten Aufruf.', 'success'); + } catch (err) { + addToast(err instanceof Error ? err.message : 'Speichern fehlgeschlagen.', 'error'); + } finally { + setIsSaving(false); + } + }; + + return ( +
+

Modell

+

+ {available.source === 'openai' + ? 'Die Auswahl stammt live von OpenAI - alle Textmodelle, die dieser Schlüssel nutzen darf.' + : 'Feste Auswahl - die Liste von OpenAI war nicht abrufbar.'} +

+ {available.error && ( +

+ OpenAI: {available.error} +

+ )} + +
+ {PURPOSE_ORDER.map((purpose) => ( +
+ + +
+ ))} + + +
+
+ ); +}; + +export const AiSettings: React.FC = () => { + const { addToast } = useToast(); + const [data, setData] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + let cancelled = false; + aiApi + .settings() + .then((result) => { + if (!cancelled) setData(result); + }) + .catch((err) => { + if (!cancelled) { + addToast(err instanceof Error ? err.message : 'KI-Einstellungen nicht erreichbar.', 'error'); + } + }) + .finally(() => { + if (!cancelled) setIsLoading(false); + }); + return () => { + cancelled = true; + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + if (isLoading) return

Wird geladen...

; + if (!data) return null; + + return ( +
+ setData((prev) => (prev ? { ...prev, key, available } : prev))} + /> + setData((prev) => (prev ? { ...prev, models } : prev))} + /> +
+ ); +}; diff --git a/src/components/settings/ScannerSettings.tsx b/src/components/settings/ScannerSettings.tsx index 1680d34..b1eb9d4 100644 --- a/src/components/settings/ScannerSettings.tsx +++ b/src/components/settings/ScannerSettings.tsx @@ -109,7 +109,6 @@ export const ScannerSettings: React.FC = () => { const isScanningActive = values.scanning_active === 'true'; const emailActive = values.email_notifications_active === 'true'; - const keyStored = values.openai_api_key === SECRET_MASK; const appliedCheckActive = values.applied_check_active === 'true'; const periodDays = Math.max(1, Number.parseInt(values.applied_check_days, 10) || 14); const periodFactor = periodUnit === 'weeks' ? 7 : 1; @@ -190,7 +189,7 @@ export const ScannerSettings: React.FC = () => {
{
-
- - set('openai_api_key', event.target.value)} - placeholder={ - keyStored - ? 'Leer lassen, um den gespeicherten Key zu behalten' - : 'sk-proj-...' - } - className={inputClass} - /> -
-
= ({ initialTab }) {tab === 'mail' && isAdmin && } {tab === 'sso' && isAdmin && } {tab === 'scanner' && isAdmin && } + {tab === 'ki' && isAdmin && } {tab === 'whisper' && } ); diff --git a/src/lib/api.ts b/src/lib/api.ts index 4bab665..e0861dc 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -166,6 +166,57 @@ export const msSecretApi = { request<{ ok: true; secret: MsSecretStatus }>('/auth/microsoft-secret', { method: 'DELETE' }), }; +// ---------- KI: OpenAI-Schluessel und Modellwahl (nur admin) ---------- + +export interface AiKeyStatus { + configured: boolean; + /** 'db' = in den Einstellungen hinterlegt, 'env' = aus server/.env */ + source: 'db' | 'env' | null; + /** Letzte vier Zeichen - mehr gibt der Server nie heraus. */ + last4: string | null; + env_fallback: boolean; +} + +export type AiPurpose = 'matching' | 'applied' | 'search'; + +export interface AiModelSetting { + label: string; + model: string; + fallback: string; +} + +export interface AiAvailableModels { + models: string[]; + /** 'openai' = live abgefragt, 'fallback' = feste Liste */ + source: 'openai' | 'fallback'; + error: string | null; +} + +export interface AiSettings { + key: AiKeyStatus; + models: Record; + available: AiAvailableModels; +} + +export const aiApi = { + settings: () => request('/ai/settings'), + saveKey: (key: string) => + request<{ ok: true; key: AiKeyStatus; available: AiAvailableModels }>('/ai/key', { + method: 'PUT', + body: JSON.stringify({ key }), + }), + /** Verwirft den hinterlegten Schluessel; ab dann gilt wieder server/.env. */ + clearKey: () => + request<{ ok: true; key: AiKeyStatus; available: AiAvailableModels }>('/ai/key', { + method: 'DELETE', + }), + saveModels: (models: Partial>) => + request<{ ok: true; models: Record }>('/ai/models', { + method: 'PUT', + body: JSON.stringify(models), + }), +}; + // ---------- Benutzerverwaltung (nur admin) ---------- export interface UserInput { diff --git a/src/lib/scannerApi.ts b/src/lib/scannerApi.ts index 7311df1..7d96cd7 100644 --- a/src/lib/scannerApi.ts +++ b/src/lib/scannerApi.ts @@ -89,7 +89,6 @@ export interface ScannerMatch { export interface ScannerSettings { scanning_active: string; search_interval: string; - openai_api_key: string; match_threshold: string; display_threshold: string; sound_notifications_active: string; @@ -108,7 +107,6 @@ export interface ScannerSettings { export const SCANNER_SETTINGS_DEFAULTS: ScannerSettings = { scanning_active: 'true', search_interval: '60', - openai_api_key: '', match_threshold: '70', display_threshold: '50', sound_notifications_active: 'true', diff --git a/src/types.ts b/src/types.ts index a8e2d94..02a956e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,9 +31,10 @@ export type SettingsTab = | 'mail' | 'sso' | 'scanner' + | 'ki' | 'whisper'; -export const ADMIN_SETTINGS_TABS: SettingsTab[] = ['users', 'mail', 'sso', 'scanner']; +export const ADMIN_SETTINGS_TABS: SettingsTab[] = ['users', 'mail', 'sso', 'scanner', 'ki']; /** * Reiter des Projekt Scanners. "Scanner" selbst ist das Dashboard und damit die