fixes before document generation refactory styles

This commit is contained in:
ValueOn AG 2026-04-29 22:54:21 +02:00
parent 5955caff61
commit 00d99f50f1
4 changed files with 69 additions and 33 deletions

View file

@ -1,5 +1,6 @@
<!-- status: plan -->
<!-- started: 2026-04-29 -->
<!-- reviewed: 2026-04-29 (critical review passed, corrections applied) -->
<!-- component: gateway, frontend-nyla -->
# AI Reports: Generisches Style-Management, AI-Call-Konfiguration, Inline-Bilder
@ -59,6 +60,10 @@ explizit und auditierbar.
- Inline-Bilder erfordern Schema-Aenderung beim `cell`/`paragraph`/
`bullet_list_item`-Content: weg von `string`, hin zu `inline-Run-
Liste` (`text` | `image` | `link` | `bold` | `italic`).
- **KEIN Backwards-Compat:** Altes String-basiertes Format wird NICHT
weiter unterstuetzt. Renderer bekommen NUR das neue Inline-Run-
Modell. Alte Workflow-Runs mit altem JSON-Output brechen bei erneutem
Rendering -- akzeptabler Trade-off fuer saubere Codebasis.
- Per-Node AI-Konfiguration darf das **zentrale AI-Gate** nicht
umgehen: das Gate bleibt einzige Stelle, die Neutralisierung wirklich
durchsetzt. Node-Parameter werden in den `AiCallRequest` reingefuettert
@ -86,14 +91,18 @@ explizit und auditierbar.
- NICHT: User-konfigurierbare Custom-Themes via Admin-UI.
- NICHT: Aenderung am bestehenden Neutralisierungs-Engine; nur Eingangs-
Pfad ergaenzen.
- NICHT: Backwards-Compat fuer altes JSON-Format (Clean-Break).
## Betroffene Module
- Gateway:
- `gateway/modules/serviceCenter/services/serviceAgent/coreTools/_mediaTools.py`
-- `_markdownToDocumentJson` raus, auf gemeinsamen Helper
umstellen; `renderDocument`-Tool-Schema ergaenzt um optionalen
`style`-Parameter.
-- `_markdownToDocumentJson` (nested in `_registerMediaTools`, Z. 27-163)
entfernen, Aufruf auf `subDocumentUtility.markdownToDocumentJson`
umleiten. Image-Resolution-Logik (Z. 241-277, loest fileId -> base64
aus KnowledgeStore/Chat) VERBLEIBT in `_mediaTools` als Post-
Processing-Schritt nach dem Parser-Aufruf.
`renderDocument`-Tool-Schema ergaenzt um optionalen `style`-Parameter.
- `gateway/modules/serviceCenter/services/serviceGeneration/subDocumentUtility.py`
-- alleinige MD->JSON-Funktion mit Inline-Run-Modell.
- `gateway/modules/serviceCenter/services/serviceGeneration/mainServiceGeneration.py`
@ -101,15 +110,21 @@ explizit und auditierbar.
Agent-Overrides).
- `gateway/modules/serviceCenter/services/serviceGeneration/renderers/*`
-- alle 5 Renderer auf Style-Lookup umstellen, Inline-Run-Renderer.
NUR neues Format (InlineRun); altes String-Format wird nicht mehr
unterstuetzt.
- `gateway/modules/datamodels/datamodelJson.py` -- Schema-Erweiterung
fuer Inline-Runs und `cellContent`.
- `gateway/modules/datamodels/datamodelAi.py` --
`AiCallRequest.allowedModels: Optional[List[str]]` (Whitelist).
`AiCallOptions.allowedModels: Optional[List[str]]` (Whitelist;
analog `allowedProviders` Z. 164).
- `gateway/modules/serviceCenter/services/serviceAi/mainServiceAi.py`
-- Whitelist-Check vor Modellwahl, Fail-fast wenn keiner uebrig.
-- `_calculateEffectiveModels()` (Z. ~1196, analog zu
`_calculateEffectiveProviders`); Whitelist-Check vor Modellwahl,
Fail-fast wenn keiner uebrig. `_ServicesAdapter.__getattr__`
(Z. 88-90) um `"allowedModels"` ergaenzen.
- `gateway/modules/features/graphicalEditor/nodeDefinitions/ai.py`
-- Standardparameter `requireNeutralization` + `allowedModels` zu
allen `ai.*`-Nodes (gemeinsamer Helper).
allen `ai.*`-Nodes (gemeinsamer Helper `_AI_COMMON_PARAMS`).
- `gateway/modules/workflows/methods/methodAi/actions/*.py` -- Node-
Parameter durchreichen in den `AiCallRequest`.
- `gateway/modules/serviceCenter/services/serviceAgent/conversationManager.py`
@ -123,6 +138,8 @@ explizit und auditierbar.
- Workspace-Settings: bestehender Neutralisierungs-Toggle bleibt;
neuer Multi-Select fuer `allowedModels` (Default: alle verfuegbaren
Modelle des Mandate).
- HINWEIS: Request-Model heisst `WorkspaceInputRequest` (NICHT
`WorkspaceUserInput`; siehe `routeFeatureWorkspace.py` Z. 102-113).
- Style-Vorschau (klein): Optional Snippet im FlowEditor, das den
`style`-Parameter eines `file.create`/`renderDocument`-Nodes
visualisieren kann (deferred).
@ -214,11 +231,12 @@ Neu: `inlineRuns: List[InlineRun]` mit
}
```
Backwards-kompatibel: Wenn der MD-Parser nur Text findet, bleibt es
ein einzelner Run mit `type: text`. Renderer bekommen einen Helper
Wenn der MD-Parser nur Text findet, entsteht ein einzelner Run mit
`type: text`. Renderer bekommen einen Helper
`_renderInlineRuns(runs, style, container)`, der pro Run das richtige
Element produziert (Text-Run mit Style, Inline-Image-Anchor,
Hyperlink-Run, etc.).
Hyperlink-Run, etc.). **Kein** altes `text: str`-Feld -- Renderer
arbeiten ausschliesslich mit `inlineRuns`.
**Markdown-Erkennung:** `![alt](file:xyz)` und `![alt](file:xyz "100pt")`
mitten in einem Paragraph oder in einer Tabellenzelle wird vom Parser
@ -247,10 +265,10 @@ zu einem `image`-Run. Listen-Items dasselbe.
- **`_calculateEffectiveProviders()`** macht RBAC ∩ Workflow.allowedProviders
und schreibt das in `request.options.allowedProviders` (`mainServiceAi.py`
Z. 175-178).
- **`WorkspaceUserInput.allowedProviders`** + **`requireNeutralization`**
- **`WorkspaceInputRequest.allowedProviders`** + **`requireNeutralization`**
werden vom Frontend pro Request mitgegeben
(`routeFeatureWorkspace.py` Z. 111-113) und in den
`ServiceCenterContext` gesetzt (Z. 716-719).
`ServiceCenterContext` gesetzt (Z. 713-719).
- **`ServiceCenterContext.requireNeutralization`** existiert (`context.py`
Z. 23).
- **`GET /api/system/ai-models`** liefert die verfuegbaren Modelle
@ -360,29 +378,35 @@ flowchart LR
| 2026-04-29 | Whitelist-Check vor Modellwahl; leer -> Fail-fast | Compliance: Workflow soll **deterministisch** scheitern statt stillschweigend ein nicht-erlaubtes Modell zu nehmen |
| 2026-04-29 | MD->JSON-Konsolidierung in `subDocumentUtility.py` | Bereits zentralerer Pfad als `_mediaTools` |
| 2026-04-29 | Native XLSX-Charts via openpyxl spaeter | Heute reicht PNG-Embed; Chart-API ist eigene Komplexitaet |
| 2026-04-29 | KEIN Backwards-Compat fuer altes JSON-Format | Clean-Break: alte Runs brechen, akzeptabler Trade-off fuer saubere Codebasis ohne Dispatch-Overhead |
| 2026-04-29 | `WorkspaceUserSettings` in `poweron_app` (nicht `poweron_workspace`) | Dort leben User-spezifische Instanz-Daten (FeatureAccess etc.) |
| 2026-04-29 | Image-Resolution-Logik verbleibt in `_mediaTools` (Post-Processing) | Nur der MD-Parser wird konsolidiert; fileId->base64-Auflosung ist kontextabhaengig (Chat-History, KnowledgeStore) |
| 2026-04-29 | `documentTheme` (Plan B) wird Prompt-Hint, NICHT Renderer-Parameter | Renderer hat kein Theme-Konzept; Agent leitet Style aus Hint ab |
## Umsetzungs-Checkliste
### Phase 1 -- MD->JSON konsolidieren + Inline-Runs
- [ ] `subDocumentUtility.markdownToDocumentJson` zur einzigen Quelle
machen.
- [ ] `_mediaTools._markdownToDocumentJson` durch Aufruf des Helpers
ersetzen, lokale Funktion entfernen.
machen (module-level Funktion, Z. 12+).
- [ ] `_mediaTools._markdownToDocumentJson` (nested in
`_registerMediaTools`, Z. 27-163) ENTFERNEN. Stattdessen
`subDocumentUtility.markdownToDocumentJson` aufrufen. Die Image-
Resolution-Logik (Z. 241-277: fileId -> base64 aus
KnowledgeStore/Chat) VERBLEIBT als Post-Processing nach dem
Parser-Aufruf.
- [ ] Schema-Erweiterung in `datamodels/datamodelJson.py`:
- `paragraph.inlineRuns: List[InlineRun]` (alt `text: str` als
Backwards-Compat-Feld weiter unterstuetzt).
- `paragraph.inlineRuns: List[InlineRun]` (KEIN Backwards-Compat-
Feld `text: str` -- Clean-Break).
- `bullet_list.items: List[List[InlineRun]]`.
- `table.cell` neu strukturiert: `cellContent: List[InlineRun]`
oder `cellBlocks: List[Section]` (fuer komplexere Zellen mit
eigenem Paragraph/Image-Block).
- `table.cell` neu: `cellContent: List[InlineRun]`.
- Altes String-basiertes Format wird NICHT mehr unterstuetzt.
- [ ] MD-Parser im konsolidierten Helper:
- Inline `![alt](file:xyz)` an beliebiger Position erkennen ->
`image`-Run.
- Inline `[text](url)` -> `link`-Run.
- `**bold**` / `*italic*` / `` `code` `` -> entsprechende Runs.
- Tabellen-Zellen: erkennen ob nur Text -> einzelner Text-Run;
sonst voll geparst (inkl. Bild).
- Tabellen-Zellen: voll geparst (inkl. Bild, Links, Formatierung).
- [ ] Helper `_renderInlineRuns(runs, style, container)` als gemeinsame
Spec; pro Renderer eigene Implementierung.
@ -455,7 +479,7 @@ flowchart LR
`Workflow.allowedProviders`).
- [ ] `gateway/modules/serviceCenter/services/serviceAi/mainServiceAi.py`:
- Neue private Methode `_calculateEffectiveModels()` analog zu
`_calculateEffectiveProviders()` (Z. 175-178). RBAC-Modelle ∩
`_calculateEffectiveProviders()` (Z. ~1196). RBAC-Modelle ∩
`Workflow.allowedModels``request.options.allowedModels`.
- In `_call`/`_callStream`/`callEmbedding` analog zur
Provider-Logik aufrufen und in `request.options.allowedModels`
@ -465,15 +489,17 @@ flowchart LR
- Fail-fast `RuntimeError` wenn die Filterkette leer wird, mit
Audit-Log-Zeile (modelle, provider, rbac-permitted, workflow,
node).
- [ ] `__getattr__` in `mainServiceAi.py` (Z. 88-90) erweitern:
Tuple-Liste um `"allowedModels"` ergaenzen (damit
- [ ] `_ServicesAdapter.__getattr__` in `mainServiceAi.py` (Z. 88-90)
erweitern: Tuple-Liste um `"allowedModels"` ergaenzen (damit
`service.allowedModels` analog `service.allowedProviders`
aus dem Workflow durchgereicht wird).
### Phase 5a -- Workspace User-Settings (Persistenz fuer alle drei Felder)
- [ ] Neue persistente Settings pro User × Workspace-Instanz.
Tabelle `WorkspaceUserSettings` (additiv via Auto-Init):
Tabelle `WorkspaceUserSettings` in **`poweron_app`** (dort wo
`FeatureAccess`, `FeatureInstance` etc. leben; User-spezifische
Instanz-Daten). Additiv via Auto-Init:
- `instanceId UUID NOT NULL`
- `userId UUID NOT NULL`
- `requireNeutralization BOOL DEFAULT false`
@ -486,13 +512,15 @@ flowchart LR
leer).
- `PUT /api/workspace/{instanceId}/user-settings` -- speichern
(alle drei Felder im Body).
- [ ] `WorkspaceUserInput.allowedModels: List[str] = []` (additiv,
`routeFeatureWorkspace.py` Z. 109-114). `requireNeutralization`
und `allowedProviders` sind dort schon vorhanden (Z. 112-113).
- [ ] `WorkspaceInputRequest.allowedModels: List[str] = Field(default_factory=list)`
(additiv, `routeFeatureWorkspace.py` Z. 102-113).
`requireNeutralization` und `allowedProviders` sind dort schon
vorhanden (Z. 111-112).
- [ ] In `_runWorkspaceAgent` (Z. 693+): `allowedModels` ebenso
durchreichen wie heute `allowedProviders` (Z. 716-717) -- in das
durchreichen wie heute `allowedProviders` (Z. 713-717) -- in das
`request.options.allowedModels`-Feld schreiben (siehe Phase 5
Datenmodell).
Datenmodell). Pattern analog:
`aiService.services.allowedModels = allowedModels`.
- [ ] Frontend Workspace:
- Workspace-Settings-Tab/Panel mit allen drei Feldern:
- Toggle `requireNeutralization`.
@ -535,14 +563,20 @@ flowchart LR
### Phase 6 -- Trustee-Templates anpassen (entkoppelt vom Bau-Plan B)
- [ ] In `mainTrustee.py`-Templates: `style`-Block in `aiPrompt`-Node
Parametern setzen (Finanzreport-Defaults: dunkelblaue Headings,
- [ ] In `mainTrustee.py`-Templates: neuen Node-Parameter `style`-Block
setzen (Finanzreport-Defaults: dunkelblaue Headings,
konservatives Calibri etc.) -- damit Trustee out-of-the-box gut
aussieht.
aussieht. Der in Plan B gesetzte `documentTheme: "finance"`
wird als Hint fuer den Agent im Prompt benutzt (NICHT als
Renderer-Parameter); der Agent soll daraus seinen `style`-Block
ableiten.
- [ ] `requireNeutralization: true` falls Trustee-Daten sensibel
(entscheidet Compliance-Doku, Default empfohlen).
- [ ] `allowedModels` pro Trustee-Workflow optional pinned (z.B. nur
private LLM fuer Finance-Daten).
- [ ] `documentTheme`-Parameter im Budget-Template (aus Plan B) in den
Prompt als Kontext-Hint einfuegen, statt als separaten
Renderer-Parameter. Der Renderer kennt KEIN Theme-Konzept.
### Phase 7 -- Tests / Snapshots

View file

@ -14,6 +14,8 @@ Skip: reine Refactors, Formatting, Lint, Dep-Bumps, Test-only, Wiki-Tippfehler.
## 2026-04-29
- 2026-04-29 | feat | gateway, frontend-nyla | **B: Trustee Budget-Vergleich auf Excel umgestellt.** `mainTrustee.py` Template: `resultType: "xlsx"` + `documentTheme: "finance"` hart gesetzt. Prompt komplett refaktoriert: 1 Tabelle alle Konten, 1 Uebersichts-Chart (kein pro-Konto-Chart), Management-Summary. Frontend: Hinweistext "Excel-Bericht" im Budget-Tab ergaenzt. XLSX-Renderer (PNG-unter-Tabelle) verifiziert. (c-work: `3-validate/2026-04-trustee-budget-comparison-refactor.md`)
- 2026-04-29 | feat | gateway, frontend-nyla | **A2 Workflow-Run-Workspace + targetFeatureInstanceId implementiert.** Phase 1: `AutoWorkflow.targetFeatureInstanceId` (Pydantic + DB), createWorkflow-Fallback, Save-Validation (400 fuer non-template ohne targetId), Execute-RBAC-Check, `executeGraph` Placeholder-Substitution (`{{featureInstanceId}}`), Scheduler-Durchreichung, `_copyTemplateWorkflows` explizites Setzen, idempotente Boot-Backfill-Migration. Phase 2: FlowEditor CanvasHeader "Ziel-Instanz" Dropdown mit FeatureStore-Integration, Save/Load mit `targetFeatureInstanceId`. Phase 3: Neuer Backend-Endpoint `GET /api/automations/runs` + `GET /api/automations/runs/{runId}/detail` (RBAC via FeatureAccess), neuer "Workspace" Tab in AutomationsDashboardPage mit Run-Liste + Detail-View (Steps, Files, Download). Phase 4: TrusteeAnalyseView inline-Results durch "Im Workspace ansehen"-Link ersetzt, TrusteeAbschlussView Workspace-Link nach Completion ergaenzt. (c-work: `1-plan/2026-04-trustee-workflow-audit-and-run-workspace.md`)
- 2026-04-29 | docs | wiki | **Plan A2 finalisiert: Trustee Workflow-Audit + Generischer Workflow-Run-Workspace.** Cross-Check gegen Codebase (12 Punkte verifiziert, 4 Korrekturen eingearbeitet): `executeGraph` hat keine Placeholder-Substitution (muss neu gebaut werden), `_copyTemplateWorkflows` setzt `featureInstanceId` nicht im Payload (implizit via GE-Interface), `TrusteeAbschlussView` hat kein `resultText`/`resultDocuments` (nur status/summary), 7 Trustee-Templates statt 5 im Audit. Risiko-Sektion ergaenzt. (c-work: `1-plan/2026-04-trustee-workflow-audit-and-run-workspace.md`)