mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
feat(project-doc-bot): migrate to shared-llm, remove OpenAI dependency
Migrate matrix-project-doc-bot from raw fetch to @manacore/shared-llm and remove the unused openai npm package. The bot was already using mana-llm and mana-stt (not OpenAI directly), but the code still had raw fetch calls and the openai package installed. Changes: - generation.service.ts: raw fetch → llm.chat() via LlmClientService - app.module.ts: add LlmModule.forRootAsync() - Remove openai dependency (was unused in code) - Update CLAUDE.md: document actual AI stack (mana-llm + mana-stt) - Update TECH_STACK_INDEPENDENCE.md: mark Prio 1-3 as completed - Prio 1: Picture App → mana-image-gen ✅ - Prio 2: Project Doc Bot → Ollama + mana-stt ✅ - Prio 3: All LLM calls via mana-llm ✅ - Self-hosted percentage: 75% → ~80% Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
357fbb3d50
commit
62c5dddab0
6 changed files with 136 additions and 91 deletions
|
|
@ -94,18 +94,13 @@ Brevo ist SPOF für alle Transaktions-Emails (Verifizierung, Passwort-Reset).
|
|||
|
||||
#### 2.1 Alle LLM-Requests über mana-llm routen
|
||||
|
||||
**Aufwand:** 1 Woche | **Impact:** Hoch
|
||||
**Status: ✅ ERLEDIGT** (2026-03-24)
|
||||
|
||||
Aktuell nutzen einige Apps direkt Cloud-SDKs (OpenAI, Gemini, Azure). Wenn alles über `mana-llm` läuft:
|
||||
- Ein Switch reicht um Provider zu wechseln
|
||||
- Zentrales Logging, Rate-Limiting, Cost-Tracking
|
||||
- Einfacherer Wechsel zu lokalen Modellen
|
||||
|
||||
**Betroffene Apps:**
|
||||
- Context App → `apps/context/apps/backend/src/ai/ai.service.ts`
|
||||
- NutriPhi → Google Gemini SDK direkt
|
||||
- Planta → Google Gemini SDK direkt
|
||||
- Matrix Project Doc Bot → OpenAI SDK direkt
|
||||
Alle 9 Backends nutzen jetzt `@manacore/shared-llm` → `mana-llm` Gateway:
|
||||
- Auth, Chat, Context, NutriPhi, Planta, Traces, ManaDeck, Bot Services, Matrix Bots
|
||||
- Google Gemini als automatischer Fallback wenn Ollama überlastet
|
||||
- OpenAI SDK komplett entfernt (Project Doc Bot)
|
||||
- Google Gemini SDK entfernt (ManaDeck)
|
||||
|
||||
#### 2.2 PostgreSQL Backup stärken
|
||||
|
||||
|
|
@ -201,9 +196,9 @@ NutriPhi und Planta nutzen Google Gemini Vision. Alternativen via Ollama:
|
|||
|
||||
| Prio | Maßnahme | Aufwand | Gewinn |
|
||||
|------|----------|---------|--------|
|
||||
| **1** | Picture App → mana-image-gen | 1-2 Tage | Replicate-Kosten = 0, volle Kontrolle |
|
||||
| **2** | Project Doc Bot → Ollama + mana-stt | 1 Tag | OpenAI-Abhängigkeit weg |
|
||||
| **3** | Alle LLM-Calls über mana-llm routen | 1 Woche | Zentrale Provider-Kontrolle |
|
||||
| ~~**1**~~ | ~~Picture App → mana-image-gen~~ | ✅ Erledigt | Lokales FLUX.2 klein als Default, Replicate für Premium |
|
||||
| ~~**2**~~ | ~~Project Doc Bot → Ollama + mana-stt~~ | ✅ Erledigt | OpenAI SDK entfernt, nutzt mana-llm + mana-stt |
|
||||
| ~~**3**~~ | ~~Alle LLM-Calls über mana-llm routen~~ | ✅ Erledigt | @manacore/shared-llm + Google Fallback |
|
||||
| **4** | PostgreSQL Backup mit pgBackRest | 1-2 Tage | Disaster Recovery |
|
||||
| **5** | Brevo → Postal/Stalwart | 2-3 Tage | Email-Unabhängigkeit |
|
||||
| **6** | Landing Pages self-hosted | 0.5 Tage | Cloudflare Pages weg |
|
||||
|
|
@ -216,8 +211,15 @@ NutriPhi und Planta nutzen Google Gemini Vision. Alternativen via Ollama:
|
|||
|
||||
## Zusammenfassung
|
||||
|
||||
**Aktuell self-hosted:** ~75% der Infrastruktur
|
||||
**Nach Roadmap (Prio 1-6):** ~90%
|
||||
**Aktuell self-hosted:** ~80% der Infrastruktur (Stand: 2026-03-24)
|
||||
**Nach Roadmap (Prio 4-6):** ~90%
|
||||
**Unvermeidbare Cloud-Abhängigkeiten:** Stripe (Payment Gateway), Google OAuth (Contacts API)
|
||||
|
||||
Der Stack ist bereits sehr gut aufgestellt. Die größten Quick Wins sind die Integration von `mana-image-gen` in die Picture App und das Routing aller LLM-Calls über `mana-llm`. Die kritischste Verbesserung ist die Backup-Strategie und Server-Redundanz.
|
||||
**Erledigte Meilensteine (2026-03-24):**
|
||||
- ✅ Alle LLM-Calls über `mana-llm` geroutet (9 Backends, `@manacore/shared-llm`)
|
||||
- ✅ Google Gemini Fallback in mana-llm (automatisch bei Ollama-Überlastung)
|
||||
- ✅ Picture App nutzt lokales `mana-image-gen` (FLUX.2 klein) als Default
|
||||
- ✅ Project Doc Bot: OpenAI SDK komplett entfernt
|
||||
- ✅ ManaDeck: Google Gemini SDK entfernt
|
||||
|
||||
**Nächste Schritte:** PostgreSQL Backup (Prio 4), E-Mail-Unabhängigkeit (Prio 5), Landing Pages self-hosted (Prio 6).
|
||||
|
|
|
|||
132
pnpm-lock.yaml
generated
132
pnpm-lock.yaml
generated
|
|
@ -8564,9 +8564,6 @@ importers:
|
|||
matrix-bot-sdk:
|
||||
specifier: ^0.7.1
|
||||
version: 0.7.1
|
||||
openai:
|
||||
specifier: ^4.77.0
|
||||
version: 4.104.0(encoding@0.1.13)(ws@8.18.3)(zod@3.25.76)
|
||||
postgres:
|
||||
specifier: ^3.4.5
|
||||
version: 3.4.7
|
||||
|
|
@ -8579,7 +8576,7 @@ importers:
|
|||
devDependencies:
|
||||
'@nestjs/cli':
|
||||
specifier: ^10.4.9
|
||||
version: 10.4.9(esbuild@0.27.4)
|
||||
version: 10.4.9(esbuild@0.19.12)
|
||||
'@nestjs/schematics':
|
||||
specifier: ^10.2.3
|
||||
version: 10.2.3(chokidar@3.6.0)(typescript@5.9.3)
|
||||
|
|
@ -31227,7 +31224,6 @@ snapshots:
|
|||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
optional: true
|
||||
|
||||
'@expo/code-signing-certificates@0.0.5':
|
||||
dependencies:
|
||||
|
|
@ -31473,7 +31469,6 @@ snapshots:
|
|||
optionalDependencies:
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optional: true
|
||||
|
||||
'@expo/dom-webview@55.0.3(expo@52.0.47)(react-native@0.76.7(@babel/core@7.28.5)(@babel/preset-env@7.28.5(@babel/core@7.28.5))(@types/react@18.3.27)(encoding@0.1.13)(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
|
|
@ -31542,7 +31537,6 @@ snapshots:
|
|||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.4(react@19.2.4))(react-native-webview@13.12.2(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optional: true
|
||||
|
||||
'@expo/env@0.4.2':
|
||||
dependencies:
|
||||
|
|
@ -31724,7 +31718,6 @@ snapshots:
|
|||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
stacktrace-parser: 0.1.11
|
||||
optional: true
|
||||
|
||||
'@expo/mcp-tunnel@0.0.8':
|
||||
dependencies:
|
||||
|
|
@ -31939,7 +31932,7 @@ snapshots:
|
|||
postcss: 8.4.49
|
||||
resolve-from: 5.0.0
|
||||
optionalDependencies:
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.12.2(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.4(react@19.2.4))(react-native-webview@13.12.2(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- supports-color
|
||||
|
|
@ -32246,7 +32239,7 @@ snapshots:
|
|||
'@expo/json-file': 10.0.12
|
||||
'@react-native/normalize-colors': 0.83.2
|
||||
debug: 4.4.3
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.12.2(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.4(react@19.2.4))(react-native-webview@13.12.2(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.7.3
|
||||
xml2js: 0.6.0
|
||||
|
|
@ -32320,7 +32313,6 @@ snapshots:
|
|||
react-dom: 19.2.4(react@19.2.4)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
'@expo/rudder-sdk-node@1.1.1(encoding@0.1.13)':
|
||||
dependencies:
|
||||
|
|
@ -32443,7 +32435,6 @@ snapshots:
|
|||
expo-font: 55.0.4(expo@55.0.5)(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optional: true
|
||||
|
||||
'@expo/ws-tunnel@1.0.6': {}
|
||||
|
||||
|
|
@ -33780,6 +33771,32 @@ snapshots:
|
|||
- uglify-js
|
||||
- webpack-cli
|
||||
|
||||
'@nestjs/cli@10.4.9(esbuild@0.19.12)':
|
||||
dependencies:
|
||||
'@angular-devkit/core': 17.3.11(chokidar@3.6.0)
|
||||
'@angular-devkit/schematics': 17.3.11(chokidar@3.6.0)
|
||||
'@angular-devkit/schematics-cli': 17.3.11(chokidar@3.6.0)
|
||||
'@nestjs/schematics': 10.2.3(chokidar@3.6.0)(typescript@5.7.2)
|
||||
chalk: 4.1.2
|
||||
chokidar: 3.6.0
|
||||
cli-table3: 0.6.5
|
||||
commander: 4.1.1
|
||||
fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.19.12))
|
||||
glob: 10.4.5
|
||||
inquirer: 8.2.6
|
||||
node-emoji: 1.11.0
|
||||
ora: 5.4.1
|
||||
tree-kill: 1.2.2
|
||||
tsconfig-paths: 4.2.0
|
||||
tsconfig-paths-webpack-plugin: 4.2.0
|
||||
typescript: 5.7.2
|
||||
webpack: 5.97.1(esbuild@0.19.12)
|
||||
webpack-node-externals: 3.0.0
|
||||
transitivePeerDependencies:
|
||||
- esbuild
|
||||
- uglify-js
|
||||
- webpack-cli
|
||||
|
||||
'@nestjs/cli@10.4.9(esbuild@0.27.4)':
|
||||
dependencies:
|
||||
'@angular-devkit/core': 17.3.11(chokidar@3.6.0)
|
||||
|
|
@ -36066,8 +36083,7 @@ snapshots:
|
|||
|
||||
'@react-native/assets-registry@0.83.2': {}
|
||||
|
||||
'@react-native/assets-registry@0.84.1':
|
||||
optional: true
|
||||
'@react-native/assets-registry@0.84.1': {}
|
||||
|
||||
'@react-native/babel-plugin-codegen@0.76.7(@babel/preset-env@7.28.5(@babel/core@7.28.5))':
|
||||
dependencies:
|
||||
|
|
@ -36368,7 +36384,6 @@ snapshots:
|
|||
nullthrows: 1.1.1
|
||||
tinyglobby: 0.2.15
|
||||
yargs: 17.7.2
|
||||
optional: true
|
||||
|
||||
'@react-native/community-cli-plugin@0.76.7(@babel/core@7.28.5)(@babel/preset-env@7.28.5(@babel/core@7.28.5))(encoding@0.1.13)':
|
||||
dependencies:
|
||||
|
|
@ -36467,7 +36482,6 @@ snapshots:
|
|||
- bufferutil
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
optional: true
|
||||
|
||||
'@react-native/debugger-frontend@0.76.7': {}
|
||||
|
||||
|
|
@ -36479,8 +36493,7 @@ snapshots:
|
|||
|
||||
'@react-native/debugger-frontend@0.83.2': {}
|
||||
|
||||
'@react-native/debugger-frontend@0.84.1':
|
||||
optional: true
|
||||
'@react-native/debugger-frontend@0.84.1': {}
|
||||
|
||||
'@react-native/debugger-shell@0.83.2':
|
||||
dependencies:
|
||||
|
|
@ -36494,7 +36507,6 @@ snapshots:
|
|||
fb-dotslash: 0.5.8
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
'@react-native/dev-middleware@0.76.7':
|
||||
dependencies:
|
||||
|
|
@ -36607,7 +36619,6 @@ snapshots:
|
|||
- bufferutil
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
optional: true
|
||||
|
||||
'@react-native/gradle-plugin@0.76.7': {}
|
||||
|
||||
|
|
@ -36619,8 +36630,7 @@ snapshots:
|
|||
|
||||
'@react-native/gradle-plugin@0.83.2': {}
|
||||
|
||||
'@react-native/gradle-plugin@0.84.1':
|
||||
optional: true
|
||||
'@react-native/gradle-plugin@0.84.1': {}
|
||||
|
||||
'@react-native/js-polyfills@0.76.7': {}
|
||||
|
||||
|
|
@ -36632,8 +36642,7 @@ snapshots:
|
|||
|
||||
'@react-native/js-polyfills@0.83.2': {}
|
||||
|
||||
'@react-native/js-polyfills@0.84.1':
|
||||
optional: true
|
||||
'@react-native/js-polyfills@0.84.1': {}
|
||||
|
||||
'@react-native/metro-babel-transformer@0.76.7(@babel/core@7.28.5)(@babel/preset-env@7.28.5(@babel/core@7.28.5))':
|
||||
dependencies:
|
||||
|
|
@ -36669,8 +36678,7 @@ snapshots:
|
|||
|
||||
'@react-native/normalize-colors@0.83.2': {}
|
||||
|
||||
'@react-native/normalize-colors@0.84.1':
|
||||
optional: true
|
||||
'@react-native/normalize-colors@0.84.1': {}
|
||||
|
||||
'@react-native/virtualized-lists@0.76.7(@types/react@18.3.27)(react-native@0.76.7(@babel/core@7.28.5)(@babel/preset-env@7.28.5(@babel/core@7.28.5))(@types/react@18.3.27)(encoding@0.1.13)(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
|
|
@ -36779,7 +36787,6 @@ snapshots:
|
|||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.2.14
|
||||
optional: true
|
||||
|
||||
'@react-navigation/bottom-tabs@7.15.5(@react-navigation/native@7.1.33(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.6.2(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-screens@4.16.0(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)':
|
||||
dependencies:
|
||||
|
|
@ -42292,7 +42299,7 @@ snapshots:
|
|||
resolve-from: 5.0.0
|
||||
optionalDependencies:
|
||||
'@babel/runtime': 7.28.4
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.0(react@19.2.0))(react-native-webview@13.12.2(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.4(react@19.2.4))(react-native-webview@13.12.2(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- supports-color
|
||||
|
|
@ -45397,7 +45404,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
optional: true
|
||||
|
||||
expo-audio@55.0.8(expo-asset@55.0.8(expo@55.0.5)(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3))(expo@55.0.5)(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0):
|
||||
dependencies:
|
||||
|
|
@ -45567,7 +45573,6 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
optional: true
|
||||
|
||||
expo-dev-client@5.0.20(expo@52.0.47):
|
||||
dependencies:
|
||||
|
|
@ -45755,7 +45760,6 @@ snapshots:
|
|||
dependencies:
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.4(react@19.2.4))(react-native-webview@13.12.2(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optional: true
|
||||
|
||||
expo-font@13.0.4(expo@52.0.47)(react@18.3.1):
|
||||
dependencies:
|
||||
|
|
@ -45861,7 +45865,6 @@ snapshots:
|
|||
fontfaceobserver: 2.3.0
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optional: true
|
||||
|
||||
expo-glass-effect@55.0.8(expo@54.0.25)(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
|
|
@ -46001,7 +46004,6 @@ snapshots:
|
|||
dependencies:
|
||||
expo: 55.0.5(@babel/core@7.28.5)(@expo/dom-webview@55.0.3)(@expo/metro-runtime@6.1.2)(expo-router@55.0.5)(react-dom@19.2.4(react@19.2.4))(react-native-webview@13.12.2(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
optional: true
|
||||
|
||||
expo-linear-gradient@15.0.7(expo@54.0.12)(react-native@0.81.4(@babel/core@7.28.5)(@types/react@19.2.7)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
|
|
@ -46284,7 +46286,6 @@ snapshots:
|
|||
invariant: 2.2.4
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.4)
|
||||
optional: true
|
||||
|
||||
expo-notifications@55.0.12(expo@55.0.5)(react-native@0.83.2(@babel/core@7.28.5)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3):
|
||||
dependencies:
|
||||
|
|
@ -47410,7 +47411,6 @@ snapshots:
|
|||
- supports-color
|
||||
- typescript
|
||||
- utf-8-validate
|
||||
optional: true
|
||||
|
||||
exponential-backoff@3.1.3: {}
|
||||
|
||||
|
|
@ -47812,6 +47812,23 @@ snapshots:
|
|||
|
||||
forever-agent@0.6.1: {}
|
||||
|
||||
fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.19.12)):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
chalk: 4.1.2
|
||||
chokidar: 3.6.0
|
||||
cosmiconfig: 8.3.6(typescript@5.7.2)
|
||||
deepmerge: 4.3.1
|
||||
fs-extra: 10.1.0
|
||||
memfs: 3.5.3
|
||||
minimatch: 3.1.2
|
||||
node-abort-controller: 3.1.1
|
||||
schema-utils: 3.3.0
|
||||
semver: 7.7.3
|
||||
tapable: 2.3.0
|
||||
typescript: 5.7.2
|
||||
webpack: 5.97.1(esbuild@0.19.12)
|
||||
|
||||
fork-ts-checker-webpack-plugin@9.0.2(typescript@5.7.2)(webpack@5.97.1(esbuild@0.27.4)):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
|
|
@ -48573,8 +48590,7 @@ snapshots:
|
|||
|
||||
hermes-compiler@0.14.1: {}
|
||||
|
||||
hermes-compiler@250829098.0.9:
|
||||
optional: true
|
||||
hermes-compiler@250829098.0.9: {}
|
||||
|
||||
hermes-estree@0.23.1: {}
|
||||
|
||||
|
|
@ -55540,7 +55556,6 @@ snapshots:
|
|||
- bufferutil
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
optional: true
|
||||
|
||||
react-refresh@0.14.2: {}
|
||||
|
||||
|
|
@ -57249,6 +57264,17 @@ snapshots:
|
|||
ansi-escapes: 4.3.2
|
||||
supports-hyperlinks: 2.3.0
|
||||
|
||||
terser-webpack-plugin@5.3.14(esbuild@0.19.12)(webpack@5.97.1(esbuild@0.19.12)):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 4.3.3
|
||||
serialize-javascript: 6.0.2
|
||||
terser: 5.44.1
|
||||
webpack: 5.97.1(esbuild@0.19.12)
|
||||
optionalDependencies:
|
||||
esbuild: 0.19.12
|
||||
|
||||
terser-webpack-plugin@5.3.14(esbuild@0.27.4)(webpack@5.100.2(esbuild@0.27.4)):
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
|
|
@ -59317,6 +59343,36 @@ snapshots:
|
|||
- esbuild
|
||||
- uglify-js
|
||||
|
||||
webpack@5.97.1(esbuild@0.19.12):
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.7
|
||||
'@types/estree': 1.0.8
|
||||
'@webassemblyjs/ast': 1.14.1
|
||||
'@webassemblyjs/wasm-edit': 1.14.1
|
||||
'@webassemblyjs/wasm-parser': 1.14.1
|
||||
acorn: 8.15.0
|
||||
browserslist: 4.28.0
|
||||
chrome-trace-event: 1.0.4
|
||||
enhanced-resolve: 5.18.3
|
||||
es-module-lexer: 1.7.0
|
||||
eslint-scope: 5.1.1
|
||||
events: 3.3.0
|
||||
glob-to-regexp: 0.4.1
|
||||
graceful-fs: 4.2.11
|
||||
json-parse-even-better-errors: 2.3.1
|
||||
loader-runner: 4.3.1
|
||||
mime-types: 2.1.35
|
||||
neo-async: 2.6.2
|
||||
schema-utils: 3.3.0
|
||||
tapable: 2.3.0
|
||||
terser-webpack-plugin: 5.3.14(esbuild@0.19.12)(webpack@5.97.1(esbuild@0.19.12))
|
||||
watchpack: 2.4.4
|
||||
webpack-sources: 3.3.3
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- esbuild
|
||||
- uglify-js
|
||||
|
||||
webpack@5.97.1(esbuild@0.27.4):
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.7
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Matrix Project Doc Bot collects photos, voice notes, and text for projects and g
|
|||
- **Matrix**: matrix-bot-sdk
|
||||
- **Database**: Drizzle ORM + PostgreSQL
|
||||
- **Storage**: S3 (MinIO)
|
||||
- **AI**: OpenAI (Whisper for transcription, GPT-4o-mini for generation)
|
||||
- **AI**: mana-llm (Ollama/Gemma 3 for generation), mana-stt (Whisper for transcription) — fully self-hosted
|
||||
|
||||
## Commands
|
||||
|
||||
|
|
|
|||
|
|
@ -27,14 +27,15 @@
|
|||
"db:studio": "drizzle-kit studio"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.721.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.721.0",
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@manacore/matrix-bot-common": "workspace:*",
|
||||
"@manacore/shared-llm": "workspace:^",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
"@nestjs/platform-express": "^10.4.15",
|
||||
"@aws-sdk/client-s3": "^3.721.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.721.0",
|
||||
"drizzle-orm": "^0.38.3",
|
||||
"matrix-bot-sdk": "^0.7.1",
|
||||
"openai": "^4.77.0",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { LlmModule } from '@manacore/shared-llm';
|
||||
import { HealthController, createHealthProvider } from '@manacore/matrix-bot-common';
|
||||
import { DatabaseModule } from './database/database.module';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
|
|
@ -11,6 +12,14 @@ import configuration from './config/configuration';
|
|||
isGlobal: true,
|
||||
load: [configuration],
|
||||
}),
|
||||
LlmModule.forRootAsync({
|
||||
imports: [ConfigModule],
|
||||
useFactory: (config: ConfigService) => ({
|
||||
manaLlmUrl: config.get('MANA_LLM_URL') || 'http://localhost:3025',
|
||||
debug: config.get('NODE_ENV') === 'development',
|
||||
}),
|
||||
inject: [ConfigService],
|
||||
}),
|
||||
DatabaseModule,
|
||||
BotModule,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Injectable, Inject, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { eq, desc } from 'drizzle-orm';
|
||||
import { LlmClientService } from '@manacore/shared-llm';
|
||||
import { DATABASE_CONNECTION } from '../database/database.module';
|
||||
import { generations, projectItems, projects } from '../database/schema';
|
||||
import { BLOG_STYLES } from '../config/configuration';
|
||||
|
|
@ -12,16 +12,11 @@ type Database = PostgresJsDatabase<typeof schema>;
|
|||
@Injectable()
|
||||
export class GenerationService {
|
||||
private readonly logger = new Logger(GenerationService.name);
|
||||
private readonly manaLlmUrl: string;
|
||||
private readonly model: string;
|
||||
|
||||
constructor(
|
||||
@Inject(DATABASE_CONNECTION) private db: Database,
|
||||
private configService: ConfigService
|
||||
) {
|
||||
this.manaLlmUrl = this.configService.get<string>('MANA_LLM_URL') || 'http://localhost:3025';
|
||||
this.model = this.configService.get<string>('openai.model') || 'ollama/gemma3:4b';
|
||||
}
|
||||
private readonly llm: LlmClientService
|
||||
) {}
|
||||
|
||||
async generateBlogpost(projectId: string, style: keyof typeof BLOG_STYLES): Promise<string> {
|
||||
// Get project info
|
||||
|
|
@ -70,39 +65,21 @@ Erstellt am: ${project.createdAt.toLocaleDateString('de-DE')}
|
|||
|
||||
Die folgenden Inhalte wurden während des Projekts gesammelt:`;
|
||||
|
||||
const response = await fetch(`${this.manaLlmUrl}/v1/chat/completions`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
model: this.model,
|
||||
messages: [
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: contentSummary },
|
||||
],
|
||||
temperature: 0.7,
|
||||
max_tokens: 2000,
|
||||
}),
|
||||
signal: AbortSignal.timeout(120000),
|
||||
const result = await this.llm.chat(contentSummary, {
|
||||
systemPrompt,
|
||||
temperature: 0.7,
|
||||
maxTokens: 2000,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
this.logger.error(`mana-llm error: ${response.status} - ${errorText}`);
|
||||
throw new Error(`LLM generation failed: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const content = data.choices?.[0]?.message?.content || '';
|
||||
|
||||
// Save generation
|
||||
await this.db.insert(generations).values({
|
||||
projectId,
|
||||
style,
|
||||
content,
|
||||
content: result.content,
|
||||
});
|
||||
|
||||
this.logger.log(`Generated ${style} blogpost for project ${projectId}`);
|
||||
return content;
|
||||
return result.content;
|
||||
}
|
||||
|
||||
async getLatestGeneration(projectId: string) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue