11 KiB
Gateway: INT-Stabilität — Analyse (Log) und Fix-Plan
Beschreibung und Kontext
Beim Testen der Applikation auf der Integrations-Instanz (INT) mit mehreren parallelen Nutzern wurden Symptome im Gateway-Log sichtbar (u. a. gateway_log_2026-04-08T11-14-17-514Z.log). Ziel dieses Dokuments ist eine codebezogene Ursachenanalyse und ein Umsetzungs- und Testplan — ohne die Themen mit Architektur-Storys zu vermischen.
Business-Treiber: Zuverlässiger Multi-User-Betrieb (Upload/Index, Workspace-Agent, Outlook-Tools, Knowledge/Neutralisierung) und weniger „sporadische" Fehler, die Support-Zeit kosten.
Risiko bei Nicht-Umsetzung: Weiterhin nicht reproduzierbar wirkende Permission-Fehler nach erfolgreicher Verarbeitung, fehlgeschlagene OpenAI-Streaming-Calls wegen Tool-Schema, nutzloser Outlook-Tool-Flow bei UUID-Referenzen, Crashes/Fail-Safe-Sprünge bei Bild-only-Indexierung.
Abhängigkeiten: Änderungen betreffen primär gateway; keine zwingende Frontend-Änderung, ausser Tool-Beschreibungen/UX explizit angepasst werden.
Fokus und kritische Details
Thema A — Management-Interface: globaler Singleton
- Fragil:
interfaceDbManagement.getInterface()liefert eine gemeinsameComponentObjects-Instanz ("default"); jeder Aufruf setztsetUserContextauf demselben Objekt. - Edge Case: Async-Pfade (z. B.
_autoIndexFilemitawait knowledgeService.indexFile) — zwischen Start undupdateFilekann ein anderer Request den Kontext überschreiben →PermissionErroraufFileItem.updatetrotz erfolgreicher Indexierung. - Code:
gateway/modules/interfaces/interfaceDbManagement.py,gateway/modules/routes/routeDataFiles.py(_autoIndexFile). - Fix:
_autoIndexFileholtmgmtInterfacenach dem letztenawaitfrisch. Singleton bleibt bestehen — vollständige Ablösung ist separates Architektur-Thema.
Thema B — Agent-Tool-JSON-Schema: Arrays ohne items
- Fragil:
ActionToolAdaptermapptList[str]auf JSON-Schematype: arrayohneitems. - Edge Case: OpenAI lehnt Tools mit HTTP 400 ab (array schema missing items); Failover zu anderen Providern maskiert das Problem.
- Code:
gateway/modules/serviceCenter/services/serviceAgent/actionToolAdapter.py; betroffene Aktion u. a.ai.process(methodAi.py, ParameterdocumentList). - Fix: Neues
_ARRAY_ITEMS_MAPPINGordnet Python-Array-Typen dem korrektenitems-Schema zu._convertParameterSchemasetzt beitype: "array"automatischitems(Fallback:{"type": "string"}).
Thema C — Outlook: Referenzformat vs. Lookup
- Fragil:
listConnectionszeigt u. a.id: <uuid>;getUserConnectionFromConnectionReferenceparst nurconnection:{authority}:{username}. - Edge Case: Modell übergibt UUID an Outlook-Tools → „Connection not found".
- Code:
coreTools/_connectionTools.py,mainServiceChat.getUserConnectionFromConnectionReference,methodOutlook/helpers/connection.py. - Fix:
listConnectionsgibt jetztconnection:{authority}:{username}aus statt UUIDs.getUserConnectionFromConnectionReferencehat UUID-Fallback: wenn Format nichtconnection:…, wird nach Connection-ID gesucht.
Thema D — Knowledge: _neutralSvc bei nur Bildern
- Bug:
_neutralSvcwird nur im Zweig mit Textobjekten gesetzt; Bild-Neutralisierung nutzt_neutralSvcdanach — bei keinen Textobjekten →UnboundLocalError(im Log als fail-safe sichtbar). - Code:
gateway/modules/serviceCenter/services/serviceKnowledge/mainServiceKnowledge.py(indexFile). - Fix:
_neutralSvcwird vor Text- und Bild-Block initialisiert (None), sobald_shouldNeutralizewahr ist. Bild-Block prüft_neutralSvcin der Bedingung.
Thema E — Workspace: Mandats-Kontext aus zwei Quellen
- Fragil:
_getChatInterfacenutztcontext.mandateId;ServiceCenterContextfür den Agent nutzt Mandat aus_validateInstanceAccess(Instanz). - Edge Case: Unterschiedliche
interfaceDbChat-Cache-Keys für „denselben" Workspace → seltene Inkonsistenzen (Workflow sichtbar / nicht sichtbar). - Code:
gateway/modules/features/workspace/routeFeatureWorkspace.py. - Fix:
_getChatInterfaceakzeptiert optionalenmandateId-Parameter. Alle 34_validateInstanceAccess-Aufrufe entpacken den Return-Wert. Alle_getChatInterface- undServiceCenterContext-Aufrufe nutzen die validierte Instanz-mandateId.
Thema F — Chat: createMessage / getWorkflow → None
- Fragil:
getWorkflowliefertNonebei leerem RBAC-Recordset und bei Exceptions beim Validieren desChatWorkflow-Modells;createMessagemeldet pauschal „No access to workflow". - Edge Case: Agent-Lauf endet „complete", Persistenz der Assistant-Message schlägt fehl — Ursache ohne besseres Logging schwer trennbar.
- Code:
gateway/modules/interfaces/interfaceDbChat.py. - Fix:
getWorkflowunterscheidet RBAC-leer (debug: "RBAC filter or not found") vs. Validierungsfehler (error: "data validation failed").createMessageloggtwarningmit Verweis auf Ursache.
Ziel und Nicht-Ziele
- Ziel: Die oben genannten konkreten Defekte/Risiken beheben oder absichern; INT- und Last-Szenarien reproduzierbar testen; Logging dort verbessern, wo die Ursache heute verschleiert wird.
- Explizit NICHT: Grossrefactor des gesamten Service-Centers; neue Features; umfassende Wiki-b-reference Pflege (erst nach Abschluss laut README-Lebenszyklus).
Betroffene Module
- Gateway:
interfaceDbManagement,routeDataFiles,actionToolAdapter,mainServiceChat,mainServiceKnowledge,routeFeatureWorkspace,interfaceDbChat, Agent-Core-Tools (_connectionTools), optionalconnection.py(Outlook). - Frontend: nein (ausser spätere Texte/Hinweise für Connection-Referenz — optional).
- DB-Migration: nein (für diese Fixes nicht erwartet).
- Andere Komponenten: nein.
Entscheidungen
| Datum | Entscheidung | Begründung |
|---|---|---|
| 2026-04-08 | Plan-Dokument angelegt | INT-Log + Code-Review; Umsetzung folgt in 2-build. |
| 2026-04-11 | Themen A–F umgesetzt (pragmatische Fixes) | Kein Grossrefactor Singleton; stattdessen Re-Acquire nach await + konsistente mandateId-Übergabe. |
Umsetzungs-Checkliste (Fix-Reihenfolge empfohlen)
- D
_neutralSvc/ Bildpfad inmainServiceKnowledge.indexFileabsichern —_neutralSvcwird vor Text- und Bild-Block initialisiert; Bild-Block prüft_neutralSvcin der Bedingung. Datei:serviceKnowledge/mainServiceKnowledge.py. - B JSON-Schema für
List[str]/List[int]inactionToolAdapter— neues_ARRAY_ITEMS_MAPPING;_convertParameterSchemasetzt beitype: "array"automatischitems. Datei:serviceAgent/actionToolAdapter.py. - C Connection-Lookup:
listConnectionsgibtconnection:{authority}:{username}aus statt UUIDs;getUserConnectionFromConnectionReferencehat UUID-Fallback. Dateien:coreTools/_connectionTools.py,mainServiceChat.py. - A Management-Interface: pragmatischer Fix —
_autoIndexFileholtmgmtInterfacenach dem letztenawaitfrisch. Singleton bleibt; vollständige Ablösung ist separates Architektur-Thema. Datei:routes/routeDataFiles.py. - E Workspace
mandateId:_getChatInterfaceakzeptiert optionalenmandateId-Parameter; alle 34_validateInstanceAccess-Aufrufe entpacken den Return-Wert; alle_getChatInterface- undServiceCenterContext-Aufrufe nutzen die validierte Instanz-mandateId. Datei:features/workspace/routeFeatureWorkspace.py. - F
getWorkflow/createMessageLogging:getWorkflowunterscheidet RBAC-leer (debug) vs. Validierungsfehler (error);createMessageloggtwarningmit Verweis auf Ursache. Datei:interfaces/interfaceDbChat.py.
Weitere Checkliste aus Template:
- API-Endpunkte — keine Signaturänderung;
_getChatInterfacehat neuen optionalen Parameter (intern) - DB-Schema / Migration — nein (nicht nötig)
- Frontend-Komponenten — nein
- RBAC / Permissions — keine Änderung; Fix E stellt sicher, dass Cache-Keys konsistent sind
- Neutralisierung betroffen? — ja (Thema D, behoben)
- Navigation / Routing — nein
- Billing-Impact? — nein
Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio | Status |
|---|---|---|---|
| AC1 | Given eine Datei mit nur Bild-contentObjects und aktiver Neutralisierung, When indexFile läuft, Then kein UnboundLocalError und definiertes Verhalten (OK/skip mit Log). |
must | done |
| AC2 | Given generiertes Tool-Schema für ai_process, When es an die OpenAI-kompatible API geht, Then documentList ist ein array mit items (kein 400 wegen fehlender items). |
must | done |
| AC3 | Given listConnections liefert eine Verbindungs-Referenz, When ein Outlook-Tool dieselbe Referenz nutzt, Then Verbindung wird aufgelöst (Format connection:… oder UUID-Fallback). |
must | done |
| AC4 | Given zwei parallele Uploads/Auto-Index-Läufe unterschiedlicher User, When Indexierung endet, Then updateFile(..., active) schlägt nicht wegen fremdem User-Kontext fehl. |
must | done (Re-Acquire) |
| AC5 | Given Workspace-Stream mit gültiger Instanz, When Chat-Interface und Agent-Chat-Service erzeugt werden, Then identische effektive mandateId/featureInstanceId-Kombination für den Chat-Cache. |
should | done |
| AC6 | Given getWorkflow scheitert an Datenvalidierung, When createMessage läuft, Then Log enthält ursächliche Exception, nicht nur „No access". |
should | done |
Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad / Methode | Status |
|---|---|---|---|---|---|
| T1 | AC1 | unit | ja | gateway/tests/... — indexFile mit Mock neutralization, nur image contentObjects |
pending |
| T2 | AC2 | unit | ja | Test: _buildToolDefinition / Schema für ai_process → assert properties.documentList.items |
pending |
| T3 | AC3 | unit/integration | ja/teils | getUserConnectionFromConnectionReference(uuid) vs. connection:msft:user@… |
pending |
| T4 | AC4 | integration | empfohlen | Zwei parallele Requests gegen INT oder lokaler Stress-Skript + assert File-Status | pending |
| T5 | AC5 | integration | optional | Request ohne Header-Mandat, mit Instanz-ID — ein Log-Punkt für effektive Chat-Keys | pending |
| T6 | AC6 | manuell/log | teils | Nach Fix: künstlich kaputtes Workflow-Datum in DB oder temporärer Log-Level | pending |
Links
- PR: (nach Umsetzung)
- Issue: (falls extern getrackt)
- Ausgangs-Log (lokal):
local/debug/gateway_log_2026-04-08T11-14-17-514Z.log
Abschluss
- Alle Themen A–F umgesetzt (2026-04-11)
- b-reference/ aktualisiert — z. B.
b-reference/gateway/architecture.mdnur wenn Architektur-Entscheid (Singleton) dauerhaft geändert wird - TOPICS.md aktualisiert (falls neues Thema)