From 79796bd1438f6fa1d4b14a33b082d23d448b30c7 Mon Sep 17 00:00:00 2001 From: Roland Date: Sun, 17 May 2026 07:27:18 +0200 Subject: [PATCH] vor litedb --- ...2f8b1e0b-4d4d-43c8-9474-2f7ef9baca64.vsidx | Bin 6703 -> 0 bytes .../v18/DocumentLayout.backup.json | 261 +++++++++--------- .../v18/DocumentLayout.json | 173 ++++++------ AuthorBuddy.Web.csproj | 5 + Components/DiffView.razor | 31 +++ Components/Pages/Editor.razor | 27 +- Components/Pages/Settings.razor | 90 +++++- Data/AppDbContext.cs | 36 +-- Data/SettingEntity.cs | 8 + Data/UserEntity.cs | 17 ++ .../20260516151053_InitialCreate.Designer.cs | 127 +++++++++ Migrations/20260516151053_InitialCreate.cs | 93 +++++++ Migrations/AppDbContextModelSnapshot.cs | 124 +++++++++ Program.cs | 8 +- Services/IOllamaService.cs | 6 +- Services/ISettingsService.cs | 11 +- Services/OllamaService.cs | 28 +- Services/SettingsService.cs | 126 +++++++-- author_brain.db | Bin 53248 -> 61440 bytes wwwroot/app.css | 62 +++++ 20 files changed, 951 insertions(+), 282 deletions(-) delete mode 100644 .vs/AuthorBuddy.Web.slnx/FileContentIndex/2f8b1e0b-4d4d-43c8-9474-2f7ef9baca64.vsidx create mode 100644 Components/DiffView.razor create mode 100644 Data/UserEntity.cs create mode 100644 Migrations/20260516151053_InitialCreate.Designer.cs create mode 100644 Migrations/20260516151053_InitialCreate.cs create mode 100644 Migrations/AppDbContextModelSnapshot.cs diff --git a/.vs/AuthorBuddy.Web.slnx/FileContentIndex/2f8b1e0b-4d4d-43c8-9474-2f7ef9baca64.vsidx b/.vs/AuthorBuddy.Web.slnx/FileContentIndex/2f8b1e0b-4d4d-43c8-9474-2f7ef9baca64.vsidx deleted file mode 100644 index 74cc3f86453e867855a580ff9bcf02686e6483ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6703 zcmb`L4~!gD9ml8J0=E4BC;!WF3S6O`?%i$gws#czcINHg+|ABxXWm}B;R@XK7FxXa zYVQg(LQ(=jMIin`Ek=+aU-m*K9LL%BXnf&Q$YtCN=)RH3iHXsTqi1hwPV;g^ZJk~}xuvvq ze0-a`x;Zv7Id=X?(wu0HPBlj`tuycDN8CsoZ*oghZQi_ixVdF&!{nwF7s!aKrly)3 z$0oL^>FF&S#_@-=Gg0nb48!e zIXR5xoQ}D2fjKL!WY9D+ICEy#KI4C$(`KudDx2`2sN4&k873GL?Xi(H1nb_9N&o*#tb4q%%TZ-+P*gRLxUMXw!GMw8B zO!&IJSZTvaf!R`Kh1;Ro&nV`cWjhl+TXCCqmKX|u)!JrJ#H|%&#b>PSb1ZudZnqAz z8rzWb%w$|x=O?tbS>^#dU$#WHZEUKtpms7FJ}ZiZz?^J8%7hg{*hedp*>3lYqz(N{ z)sC|_Jiw&Y4UFO%&6(LV%-POam}TNPvU9AHJgVDM#N$14l0C+EW=|5E%m>YxeedjP zE>>B3FtLYJgpHk*mUFJPxAys%hKgE$R&YC@zyZv(wnZCm*DMj;&Z0|OW~$C6+ifp5 zRLh%m0DBnbHgr~qEEa0Xs+*m&)gO86evbXX#C~vh${lJ?M7ESajiSSvTJ8mkPHaR! zpTzc;Y#nha`u)iRK$(9qWqEazd54jor2YuSV8z^=cQ@#Y0d@sc* zaW2Ct<5%Dm{gpVy@0ZA{$g9a~K$-Vd%3lM;{u`9PN$w!817-Z%l&>dm044s7f%0C9h?@sa|@+aiO z)Dl(uI|2gCs_3OxSvPqsx zo=2_+CC|@Lo**}Z;&+nrW>Dr$QNNY?3n*X2@y}6zF?k6nd0z^OzssnsnCa?BMvfsJ|Y>;oLxehrAIKzc-OLQ-2G2EBQT+-$vd} z{T-mhy_51?wBsgxI!OQ^>`A=Y0f*+q7f^0TJoxeUbN^x{k6_EFytN}Xp=UJ2rGN|Zg)r@l`i7gJv&uNEafw&q1^+uf+6-R-D^i-+}+igxquu1Z~H+)~~3Lf4C3U%R^M z>NPG#2V!@?xIyd=rfwLxVT|8d-2_MMCUw^+*9^GB${p7E_C@*j#rVB7U+m4RV&2Q= zz2$koH}9A6D{N=C-`QL4EOmEv>8?U&SE1OY3SHXoUZ%Tydb@qE(Aiz+gsM;|>O#pc zl)IMcLQii`Pg(aCx_S%c-kx%AIbZDRD)ttNez~YSmzRpm{d`|vwXZMjs|I~(<1|%Y zG2E&0o+^}7(O0EVd0P2_s%RDVsSw|R3LC1bRisp{rjm+Ej7o=8T2pDNj8aA`6DVU; z-Ka)X>h38OyGqObk_t@NO@{)%jvG2v97e`*4cuDM;z-t8l z($oFCLfL+A!B@tI7Z~{3M@AZqd|mT(;+N4ODP(UNuZNRC#g3r4m$vs1nAN zdNL5F1Bo6mXk3WC1YUpOC4sMkN<9eupsF!3hz5gbRS=mV?hoQ9NZlZ<4Qg*Njfa#O z@`ItYKkVxZRT`>B=<85>q4q;Z+>iRo$TKhE+GJx=GbF zsJmJUtJ0?VWg^&*RU-?3rti-Ms8H;kAf%~)X}Q`D0QP0*=b2| zNhL0+*w=B{#1$P^DsdRbksC+-akL_i%1A$s(m2s^G8CtAoSL|9YKwa?bjqS;5 z<2F_$W4F8UVxv2-fsC$7#X2$C7+p7dttlsF09oKBs2aOkCSHOrn3`*9{U!-a>Kaos zCNYf~R<|CRdZOwnjsW&`gYS5_Ge4}tVV$gwlQl*+f~XOxMol-;02!UB(laYz_DJG` Ro`O8U_sReO diff --git a/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.backup.json b/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.backup.json index 38c9533..f54bf47 100644 --- a/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.backup.json +++ b/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.backup.json @@ -3,29 +3,41 @@ "WorkspaceRootPath": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\", "Documents": [ { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\layout\\mainlayout.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\layout\\mainlayout.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" - }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\settings.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\settings.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" - }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\settingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\settingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\ollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\ollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\settingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\settingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\ollamasettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\ollamasettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\settings.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\settings.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\layout\\mainlayout.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\layout\\mainlayout.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" + }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\filescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\filescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -46,10 +58,6 @@ "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\llm_model.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\llm_model.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\modelstatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\modelstatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -58,18 +66,10 @@ "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\models.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\models.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\ifilescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\ifilescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\wwwroot\\lib\\bootstrap\\dist\\css\\bootstrap-utilities.css||{A5401142-F49D-43DB-90B1-F57BA349E55C}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:wwwroot\\lib\\bootstrap\\dist\\css\\bootstrap-utilities.css||{A5401142-F49D-43DB-90B1-F57BA349E55C}" @@ -122,33 +122,85 @@ }, { "$type": "Document", - "DocumentIndex": 5, - "Title": "OllamaSettings.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\OllamaSettings.cs", - "RelativeDocumentMoniker": "Models\\OllamaSettings.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\OllamaSettings.cs", - "RelativeToolTip": "Models\\OllamaSettings.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAqwAQAAAAcAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-16T13:39:46.179Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 1, "Title": "OllamaService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs", "RelativeDocumentMoniker": "Services\\OllamaService.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs", - "RelativeToolTip": "Services\\OllamaService.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAdAAAAAAAAAA==", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs*", + "RelativeToolTip": "Services\\OllamaService.cs*", + "ViewState": "AgIAADQAAAAAAAAAAAAQwEUAAABDAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-05-16T06:43:46.404Z", "EditorCaption": "" }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "SettingsService.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\SettingsService.cs", + "RelativeDocumentMoniker": "Services\\SettingsService.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\SettingsService.cs", + "RelativeToolTip": "Services\\SettingsService.cs", + "ViewState": "AgIAAMAAAAAAAAAAAAAQwMgAAAAMAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-16T06:05:12.928Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "ThemeService.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ThemeService.cs", + "RelativeDocumentMoniker": "Services\\ThemeService.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ThemeService.cs", + "RelativeToolTip": "Services\\ThemeService.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-16T13:35:33.991Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "ISettingsService.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ISettingsService.cs", + "RelativeDocumentMoniker": "Services\\ISettingsService.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ISettingsService.cs", + "RelativeToolTip": "Services\\ISettingsService.cs", + "ViewState": "AgIAAAsAAAAAAAAAAAA8wCEAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-16T13:21:26.951Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "MainLayout.razor", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Layout\\MainLayout.razor", + "RelativeDocumentMoniker": "Components\\Layout\\MainLayout.razor", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Layout\\MainLayout.razor", + "RelativeToolTip": "Components\\Layout\\MainLayout.razor", + "ViewState": "AgIAAG8AAAAAAAAAAAAAAH0AAAAtAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", + "WhenOpened": "2026-05-15T16:04:36.444Z", + "EditorCaption": "" + }, { "$type": "Document", "DocumentIndex": 6, + "Title": "OllamaSettings.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\OllamaSettings.cs", + "RelativeDocumentMoniker": "Models\\OllamaSettings.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\OllamaSettings.cs", + "RelativeToolTip": "Models\\OllamaSettings.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAqwAYAAAA6AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-16T13:39:46.179Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 9, "Title": "FileScannerService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\FileScannerService.cs", "RelativeDocumentMoniker": "Services\\FileScannerService.cs", @@ -162,58 +214,49 @@ { "$type": "Document", "DocumentIndex": 2, + "Title": "Editor.razor", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", + "RelativeDocumentMoniker": "Components\\Pages\\Editor.razor", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", + "RelativeToolTip": "Components\\Pages\\Editor.razor", + "ViewState": "AgIAAFgAAAAAAAAAAAApwGsAAAAwAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", + "WhenOpened": "2026-05-16T13:01:59.743Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "AppDbContext.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", + "RelativeDocumentMoniker": "Data\\AppDbContext.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", + "RelativeToolTip": "Data\\AppDbContext.cs", + "ViewState": "AgIAADgAAAAAAAAAAAAuwEsAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-14T10:50:13.284Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 7, "Title": "Settings.razor", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Settings.razor", "RelativeDocumentMoniker": "Components\\Pages\\Settings.razor", "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Settings.razor", "RelativeToolTip": "Components\\Pages\\Settings.razor", - "ViewState": "AgIAADcAAAAAAAAAAADwv0wAAAAAAAAAAAAAAA==", + "ViewState": "AgIAAHMAAAAAAAAAAADwv4UAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", "WhenOpened": "2026-05-15T16:43:26.6Z", "EditorCaption": "" }, { - "$type": "Document", - "DocumentIndex": 3, - "Title": "SettingsService.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\SettingsService.cs", - "RelativeDocumentMoniker": "Services\\SettingsService.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\SettingsService.cs", - "RelativeToolTip": "Services\\SettingsService.cs", - "ViewState": "AgIAAEwAAAAAAAAAAAAewFoAAAAnAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-16T06:05:12.928Z", - "EditorCaption": "" + "$type": "Bookmark", + "Name": "RST:0:0:{b3f9f954-0ca5-0091-76b4-34a47f44c954}" }, { "$type": "Document", - "DocumentIndex": 8, - "Title": "ThemeService.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ThemeService.cs", - "RelativeDocumentMoniker": "Services\\ThemeService.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ThemeService.cs", - "RelativeToolTip": "Services\\ThemeService.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-16T13:35:33.991Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 1, - "Title": "ISettingsService.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ISettingsService.cs", - "RelativeDocumentMoniker": "Services\\ISettingsService.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ISettingsService.cs*", - "RelativeToolTip": "Services\\ISettingsService.cs*", - "ViewState": "AgIAAAIAAAAAAAAAAAAxwBcAAAAbAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-16T13:21:26.951Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 14, + "DocumentIndex": 5, "Title": "IOllamaService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\IOllamaService.cs", "RelativeDocumentMoniker": "Services\\IOllamaService.cs", @@ -226,20 +269,7 @@ }, { "$type": "Document", - "DocumentIndex": 0, - "Title": "MainLayout.razor", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Layout\\MainLayout.razor", - "RelativeDocumentMoniker": "Components\\Layout\\MainLayout.razor", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Layout\\MainLayout.razor*", - "RelativeToolTip": "Components\\Layout\\MainLayout.razor*", - "ViewState": "AgIAAG8AAAAAAAAAAAAAAH0AAAAtAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", - "WhenOpened": "2026-05-15T16:04:36.444Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 10, "Title": "Program.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Program.cs", "RelativeDocumentMoniker": "Program.cs", @@ -252,7 +282,7 @@ }, { "$type": "Document", - "DocumentIndex": 9, + "DocumentIndex": 12, "Title": "App.razor", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\App.razor", "RelativeDocumentMoniker": "Components\\App.razor", @@ -263,13 +293,9 @@ "WhenOpened": "2026-05-16T05:42:06.383Z", "EditorCaption": "" }, - { - "$type": "Bookmark", - "Name": "RST:0:0:{b3f9f954-0ca5-0091-76b4-34a47f44c954}" - }, { "$type": "Document", - "DocumentIndex": 13, + "DocumentIndex": 15, "Title": "Models.razor", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Models.razor", "RelativeDocumentMoniker": "Components\\Pages\\Models.razor", @@ -282,7 +308,7 @@ }, { "$type": "Document", - "DocumentIndex": 10, + "DocumentIndex": 13, "Title": "LLM_Model.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\LLM_Model.cs", "RelativeDocumentMoniker": "Models\\LLM_Model.cs", @@ -295,7 +321,7 @@ }, { "$type": "Document", - "DocumentIndex": 12, + "DocumentIndex": 14, "Title": "ModelStatus.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\ModelStatus.cs", "RelativeDocumentMoniker": "Models\\ModelStatus.cs", @@ -306,19 +332,6 @@ "WhenOpened": "2026-05-16T13:01:24.508Z", "EditorCaption": "" }, - { - "$type": "Document", - "DocumentIndex": 11, - "Title": "Editor.razor", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", - "RelativeDocumentMoniker": "Components\\Pages\\Editor.razor", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", - "RelativeToolTip": "Components\\Pages\\Editor.razor", - "ViewState": "AgIAAFkAAAAAAAAAAAApwGAAAAAOAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", - "WhenOpened": "2026-05-16T13:01:59.743Z", - "EditorCaption": "" - }, { "$type": "Document", "DocumentIndex": 19, @@ -345,7 +358,7 @@ }, { "$type": "Document", - "DocumentIndex": 15, + "DocumentIndex": 16, "Title": "IFileScannerService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\IFileScannerService.cs", "RelativeDocumentMoniker": "Services\\IFileScannerService.cs", @@ -367,18 +380,6 @@ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-05-15T15:57:10.2Z" }, - { - "$type": "Document", - "DocumentIndex": 16, - "Title": "AppDbContext.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", - "RelativeDocumentMoniker": "Data\\AppDbContext.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", - "RelativeToolTip": "Data\\AppDbContext.cs", - "ViewState": "AgIAABoAAAAAAAAAAAAQwD4AAAAIAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-14T10:50:13.284Z" - }, { "$type": "Document", "DocumentIndex": 17, diff --git a/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.json b/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.json index 0f833c9..7199885 100644 --- a/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.json +++ b/.vs/AuthorBuddy.Web.slnx/v18/DocumentLayout.json @@ -3,16 +3,32 @@ "WorkspaceRootPath": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\", "Documents": [ { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\ollamasettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\ollamasettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\ollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\ollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\settingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\settingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\ollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\ollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + }, + { + "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\ollamasettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\ollamasettings.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\settings.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", @@ -22,10 +38,6 @@ "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\layout\\mainlayout.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\layout\\mainlayout.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\isettingsservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\filescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\filescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -46,10 +58,6 @@ "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\llm_model.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\llm_model.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\editor.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\models\\modelstatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:models\\modelstatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" @@ -58,18 +66,10 @@ "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\components\\pages\\models.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:components\\pages\\models.razor||{40D31677-CBC0-4297-A9EF-89D907823A98}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\iollamaservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\services\\ifilescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:services\\ifilescannerservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, - { - "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:data\\appdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, { "AbsoluteMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|e:\\ollama_net\\ollama\\authorbuddy.web\\wwwroot\\lib\\bootstrap\\dist\\css\\bootstrap-utilities.css||{A5401142-F49D-43DB-90B1-F57BA349E55C}", "RelativeMoniker": "D:0:0:{4F4697EF-EFFA-26AC-C8A1-C9859805D247}|AuthorBuddy.Web.csproj|solutionrelative:wwwroot\\lib\\bootstrap\\dist\\css\\bootstrap-utilities.css||{A5401142-F49D-43DB-90B1-F57BA349E55C}" @@ -124,48 +124,22 @@ "$type": "Bookmark", "Name": "RST:0:0:{b3f9f954-0ca5-0091-76b4-34a47f44c954}" }, - { - "$type": "Document", - "DocumentIndex": 2, - "Title": "OllamaService.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs", - "RelativeDocumentMoniker": "Services\\OllamaService.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs", - "RelativeToolTip": "Services\\OllamaService.cs", - "ViewState": "AgIAACMAAAAAAAAAAAAwwAAAAAAdAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-16T06:43:46.404Z", - "EditorCaption": "" - }, { "$type": "Document", "DocumentIndex": 3, - "Title": "Settings.razor", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Settings.razor", - "RelativeDocumentMoniker": "Components\\Pages\\Settings.razor", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Settings.razor", - "RelativeToolTip": "Components\\Pages\\Settings.razor", - "ViewState": "AgIAAF8AAAAAAAAAAADwv3EAAAAAAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", - "WhenOpened": "2026-05-15T16:43:26.6Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 1, "Title": "SettingsService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\SettingsService.cs", "RelativeDocumentMoniker": "Services\\SettingsService.cs", "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\SettingsService.cs", "RelativeToolTip": "Services\\SettingsService.cs", - "ViewState": "AgIAAEoAAAAAAAAAAAAAAGUAAAA7AAAAAAAAAA==", + "ViewState": "AgIAAMAAAAAAAAAAAAAQwMgAAAAMAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-05-16T06:05:12.928Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 8, + "DocumentIndex": 11, "Title": "ThemeService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ThemeService.cs", "RelativeDocumentMoniker": "Services\\ThemeService.cs", @@ -178,20 +152,20 @@ }, { "$type": "Document", - "DocumentIndex": 5, + "DocumentIndex": 4, "Title": "ISettingsService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ISettingsService.cs", "RelativeDocumentMoniker": "Services\\ISettingsService.cs", "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\ISettingsService.cs", "RelativeToolTip": "Services\\ISettingsService.cs", - "ViewState": "AgIAAAIAAAAAAAAAAAAxwBcAAAAbAAAAAAAAAA==", + "ViewState": "AgIAAAsAAAAAAAAAAAA8wCEAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-05-16T13:21:26.951Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 4, + "DocumentIndex": 8, "Title": "MainLayout.razor", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Layout\\MainLayout.razor", "RelativeDocumentMoniker": "Components\\Layout\\MainLayout.razor", @@ -204,20 +178,20 @@ }, { "$type": "Document", - "DocumentIndex": 0, + "DocumentIndex": 6, "Title": "OllamaSettings.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\OllamaSettings.cs", "RelativeDocumentMoniker": "Models\\OllamaSettings.cs", "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\OllamaSettings.cs", "RelativeToolTip": "Models\\OllamaSettings.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAqwBMAAAAgAAAAAAAAAA==", + "ViewState": "AgIAAAAAAAAAAAAAAAAqwAYAAAA6AAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-05-16T13:39:46.179Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 6, + "DocumentIndex": 9, "Title": "FileScannerService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\FileScannerService.cs", "RelativeDocumentMoniker": "Services\\FileScannerService.cs", @@ -230,7 +204,59 @@ }, { "$type": "Document", - "DocumentIndex": 14, + "DocumentIndex": 0, + "Title": "AppDbContext.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", + "RelativeDocumentMoniker": "Data\\AppDbContext.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", + "RelativeToolTip": "Data\\AppDbContext.cs", + "ViewState": "AgIAADgAAAAAAAAAAAAuwEsAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-14T10:50:13.284Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "OllamaService.cs", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs", + "RelativeDocumentMoniker": "Services\\OllamaService.cs", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\OllamaService.cs", + "RelativeToolTip": "Services\\OllamaService.cs", + "ViewState": "AgIAADQAAAAAAAAAAAAQwEUAAABDAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2026-05-16T06:43:46.404Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "Editor.razor", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", + "RelativeDocumentMoniker": "Components\\Pages\\Editor.razor", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", + "RelativeToolTip": "Components\\Pages\\Editor.razor", + "ViewState": "AgIAAFgAAAAAAAAAAAApwGsAAAAwAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", + "WhenOpened": "2026-05-16T13:01:59.743Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "Settings.razor", + "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Settings.razor", + "RelativeDocumentMoniker": "Components\\Pages\\Settings.razor", + "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Settings.razor", + "RelativeToolTip": "Components\\Pages\\Settings.razor", + "ViewState": "AgIAAHMAAAAAAAAAAADwv4UAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", + "WhenOpened": "2026-05-15T16:43:26.6Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 5, "Title": "IOllamaService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\IOllamaService.cs", "RelativeDocumentMoniker": "Services\\IOllamaService.cs", @@ -243,7 +269,7 @@ }, { "$type": "Document", - "DocumentIndex": 7, + "DocumentIndex": 10, "Title": "Program.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Program.cs", "RelativeDocumentMoniker": "Program.cs", @@ -256,7 +282,7 @@ }, { "$type": "Document", - "DocumentIndex": 9, + "DocumentIndex": 12, "Title": "App.razor", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\App.razor", "RelativeDocumentMoniker": "Components\\App.razor", @@ -269,7 +295,7 @@ }, { "$type": "Document", - "DocumentIndex": 13, + "DocumentIndex": 15, "Title": "Models.razor", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Models.razor", "RelativeDocumentMoniker": "Components\\Pages\\Models.razor", @@ -282,7 +308,7 @@ }, { "$type": "Document", - "DocumentIndex": 10, + "DocumentIndex": 13, "Title": "LLM_Model.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\LLM_Model.cs", "RelativeDocumentMoniker": "Models\\LLM_Model.cs", @@ -295,7 +321,7 @@ }, { "$type": "Document", - "DocumentIndex": 12, + "DocumentIndex": 14, "Title": "ModelStatus.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Models\\ModelStatus.cs", "RelativeDocumentMoniker": "Models\\ModelStatus.cs", @@ -306,19 +332,6 @@ "WhenOpened": "2026-05-16T13:01:24.508Z", "EditorCaption": "" }, - { - "$type": "Document", - "DocumentIndex": 11, - "Title": "Editor.razor", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", - "RelativeDocumentMoniker": "Components\\Pages\\Editor.razor", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Components\\Pages\\Editor.razor", - "RelativeToolTip": "Components\\Pages\\Editor.razor", - "ViewState": "AgIAAFkAAAAAAAAAAAApwGAAAAAOAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|", - "WhenOpened": "2026-05-16T13:01:59.743Z", - "EditorCaption": "" - }, { "$type": "Document", "DocumentIndex": 19, @@ -345,7 +358,7 @@ }, { "$type": "Document", - "DocumentIndex": 15, + "DocumentIndex": 16, "Title": "IFileScannerService.cs", "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Services\\IFileScannerService.cs", "RelativeDocumentMoniker": "Services\\IFileScannerService.cs", @@ -367,18 +380,6 @@ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2026-05-15T15:57:10.2Z" }, - { - "$type": "Document", - "DocumentIndex": 16, - "Title": "AppDbContext.cs", - "DocumentMoniker": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", - "RelativeDocumentMoniker": "Data\\AppDbContext.cs", - "ToolTip": "E:\\ollama_net\\ollama\\AuthorBuddy.Web\\Data\\AppDbContext.cs", - "RelativeToolTip": "Data\\AppDbContext.cs", - "ViewState": "AgIAABoAAAAAAAAAAAAQwD4AAAAIAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2026-05-14T10:50:13.284Z" - }, { "$type": "Document", "DocumentIndex": 17, diff --git a/AuthorBuddy.Web.csproj b/AuthorBuddy.Web.csproj index 3df2811..4204023 100644 --- a/AuthorBuddy.Web.csproj +++ b/AuthorBuddy.Web.csproj @@ -8,7 +8,12 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Components/DiffView.razor b/Components/DiffView.razor new file mode 100644 index 0000000..f9c93c6 --- /dev/null +++ b/Components/DiffView.razor @@ -0,0 +1,31 @@ +@using DiffPlex +@using DiffPlex.DiffBuilder +@using DiffPlex.DiffBuilder.Model + +
+ @if (lines is not null) + { + @foreach (var line in lines.Lines) + { +
+ @line.Position + @line.Text +
+ } + } +
+ +@code { + [Parameter] + public string Original { get; set; } = string.Empty; + + [Parameter] + public string Corrected { get; set; } = string.Empty; + + private DiffPaneModel? lines; + + protected override void OnParametersSet() + { + lines = InlineDiffBuilder.Diff(Original, Corrected); + } +} diff --git a/Components/Pages/Editor.razor b/Components/Pages/Editor.razor index ffc1079..4997b65 100644 --- a/Components/Pages/Editor.razor +++ b/Components/Pages/Editor.razor @@ -29,11 +29,18 @@ -@if (!string.IsNullOrEmpty(analysisResult)) +@if (showSpellDiff && !string.IsNullOrEmpty(correctedText)) { -
-

Ergebnis:

-
@analysisResult
+
+

Rechtschreibprüfung - Änderungen:

+ +
+} +else if (!string.IsNullOrEmpty(analysisResult)) +{ +
+

Ergebnis:

+
@analysisResult
} @@ -49,13 +56,14 @@ private bool isChecking; private double checkProgress; private string analysisResult = string.Empty; + private string originalText = string.Empty; + private string correctedText = string.Empty; + private bool showSpellDiff; protected override async Task OnInitializedAsync() { if (Action == "newproject") { - // The native folder dialog isn't available in Blazor. - // In a real app, you'd provide a form to enter project name and path. statusText = "Bitte nutze die Einstellungen zum Erstellen eines neuen Projekts."; } } @@ -67,6 +75,7 @@ isChecking = true; statusText = "Ollama analysiert Stil..."; checkProgress = 50; + showSpellDiff = false; try { @@ -91,10 +100,13 @@ isChecking = true; statusText = "Ollama prüft Rechtschreibung..."; checkProgress = 50; + showSpellDiff = false; try { - //analysisResult = await OllamaService.QuickSpellCheckAsync(editorContent); + originalText = editorContent; + correctedText = await OllamaService.QuickSpellCheckAsync(editorContent); + showSpellDiff = true; } catch (Exception ex) { @@ -114,6 +126,7 @@ isChecking = true; statusText = "Suche verwandte Fakten..."; + showSpellDiff = false; await Task.Delay(500); analysisResult = "RAG-Suche: Stelle sicher, dass ein Projekt geladen und indexiert wurde."; diff --git a/Components/Pages/Settings.razor b/Components/Pages/Settings.razor index 3841d13..f289df2 100644 --- a/Components/Pages/Settings.razor +++ b/Components/Pages/Settings.razor @@ -10,6 +10,26 @@
+
+

Benutzer

+
+ + +
+
+ +
+ + +
+
+
+
@@ -123,23 +143,31 @@ private string factCheckTemplate = string.Empty; private string spellingPrompt = string.Empty; private string newProjectName = string.Empty; + private string newUserName = string.Empty; private string statusMessage = string.Empty; private List availableModels = new(); + private List users = new(); + private int selectedUserId; protected override async Task OnInitializedAsync() { - ragModel = await SettingsService.GetRagModelAsync() ?? "llama3.2"; - styleModel = await SettingsService.GetStyleModelAsync() ?? "llama3.2"; - spellingModel = await SettingsService.GetSpellingModelAsync() ?? "phi3:mini"; - selectedTheme = await SettingsService.GetThemeAsync() ?? "light"; - ollamaUrl = await SettingsService.GetOllamaUrlAsync() ?? "http://localhost:11434"; - lektorPrompt = await SettingsService.GetLektorSystemPromptAsync() ?? string.Empty; - factCheckTemplate = await SettingsService.GetFactCheckTemplateAsync() ?? string.Empty; - spellingPrompt = await SettingsService.GetSpellingPromptAsync() ?? string.Empty; + users = await SettingsService.GetUsersAsync(); + var current = await SettingsService.GetCurrentUserAsync(); + selectedUserId = current.Id; + + var userSettings = await LoadUserSettingsAsync(); + + ragModel = userSettings.ragModel; + styleModel = userSettings.styleModel; + spellingModel = userSettings.spellingModel; + selectedTheme = userSettings.selectedTheme; + ollamaUrl = userSettings.ollamaUrl; + lektorPrompt = userSettings.lektorPrompt; + factCheckTemplate = userSettings.factCheckTemplate; + spellingPrompt = userSettings.spellingPrompt; try { - var models = await OllamaService.GetLocalModelsAsync(); availableModels = models.ToList(); } @@ -149,6 +177,47 @@ } } + private async Task<(string ragModel, string styleModel, string spellingModel, string selectedTheme, string ollamaUrl, string lektorPrompt, string factCheckTemplate, string spellingPrompt)> LoadUserSettingsAsync() + { + return ( + await SettingsService.GetRagModelAsync() ?? "llama3.2", + await SettingsService.GetStyleModelAsync() ?? "llama3.2", + await SettingsService.GetSpellingModelAsync() ?? "phi3:mini", + await SettingsService.GetThemeAsync() ?? "light", + await SettingsService.GetOllamaUrlAsync() ?? "http://localhost:11434", + await SettingsService.GetLektorSystemPromptAsync() ?? string.Empty, + await SettingsService.GetFactCheckTemplateAsync() ?? string.Empty, + await SettingsService.GetSpellingPromptAsync() ?? string.Empty + ); + } + + private async Task SwitchUser(ChangeEventArgs e) + { + var userId = int.Parse(e.Value?.ToString() ?? "0"); + await SettingsService.SetCurrentUserAsync(userId); + selectedUserId = userId; + + var userSettings = await LoadUserSettingsAsync(); + ragModel = userSettings.ragModel; + styleModel = userSettings.styleModel; + spellingModel = userSettings.spellingModel; + selectedTheme = userSettings.selectedTheme; + ollamaUrl = userSettings.ollamaUrl; + lektorPrompt = userSettings.lektorPrompt; + factCheckTemplate = userSettings.factCheckTemplate; + spellingPrompt = userSettings.spellingPrompt; + } + + private async Task AddUser() + { + if (string.IsNullOrWhiteSpace(newUserName)) return; + + var user = await SettingsService.CreateUserAsync(newUserName); + users.Add(user); + newUserName = string.Empty; + statusMessage = $"Benutzer '{user.Name}' erstellt."; + } + private async Task SaveSettings() { await SettingsService.SaveOllamaUrlAsync(ollamaUrl); @@ -164,7 +233,4 @@ statusMessage = "Einstellungen gespeichert."; await ThemeService.ApplyTheme(selectedTheme); } - - - } diff --git a/Data/AppDbContext.cs b/Data/AppDbContext.cs index 178a3fa..1338d93 100644 --- a/Data/AppDbContext.cs +++ b/Data/AppDbContext.cs @@ -8,6 +8,7 @@ public class AppDbContext : DbContext public DbSet Projects => Set(); public DbSet Settings => Set(); public DbSet DocumentMeta => Set(); + public DbSet Users => Set(); public AppDbContext(DbContextOptions options) : base(options) { } @@ -25,9 +26,19 @@ public class AppDbContext : DbContext modelBuilder.Entity(entity => { entity.ToTable("Settings"); - entity.HasKey(e => e.Key); - entity.Property(e => e.Key).HasColumnName("key"); + entity.HasKey(e => e.Id); + entity.Property(e => e.Key).HasColumnName("key").IsRequired(); entity.Property(e => e.Value).HasColumnName("value").IsRequired(); + entity.Property(e => e.UserId).HasColumnName("user_id"); + entity.Property(e => e.ProjectId).HasColumnName("project_id"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("Users"); + entity.HasKey(e => e.Id); + entity.Property(e => e.Name).HasColumnName("name").IsRequired(); + entity.Property(e => e.IsCurrent).HasColumnName("is_current"); }); modelBuilder.Entity(entity => @@ -41,7 +52,7 @@ public class AppDbContext : DbContext }); } - public static void InitializeDatabase(string connectionString) + public static void SetupVecExtension(string connectionString) { using var connection = new SqliteConnection(connectionString); connection.Open(); @@ -62,25 +73,6 @@ public class AppDbContext : DbContext using var createVecCmd = connection.CreateCommand(); createVecCmd.CommandText = @" - CREATE TABLE IF NOT EXISTS Projects ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - RootPath TEXT NOT NULL, - LastOpened DATETIME - ); - CREATE TABLE IF NOT EXISTS Settings ( - key TEXT NOT NULL UNIQUE, - value TEXT NOT NULL - ); - CREATE TABLE IF NOT EXISTS DocumentMeta ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - project_id INTEGER, - file_path TEXT UNIQUE, - last_modified DATETIME, - hash TEXT, - file_type TEXT, - FOREIGN KEY(project_id) REFERENCES Projects(id) - ); CREATE VIRTUAL TABLE IF NOT EXISTS vec_documents USING vec0( embedding float[1024] );"; diff --git a/Data/SettingEntity.cs b/Data/SettingEntity.cs index 94ba2de..fa31c04 100644 --- a/Data/SettingEntity.cs +++ b/Data/SettingEntity.cs @@ -7,8 +7,16 @@ namespace AuthorBuddy.Web.Data; public class SettingEntity { [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Required] public string Key { get; set; } = string.Empty; [Required] public string Value { get; set; } = string.Empty; + + public int? UserId { get; set; } + + public int? ProjectId { get; set; } } diff --git a/Data/UserEntity.cs b/Data/UserEntity.cs new file mode 100644 index 0000000..5070a76 --- /dev/null +++ b/Data/UserEntity.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace AuthorBuddy.Web.Data; + +[Table("Users")] +public class UserEntity +{ + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + [Required] + public string Name { get; set; } = string.Empty; + + public bool IsCurrent { get; set; } +} diff --git a/Migrations/20260516151053_InitialCreate.Designer.cs b/Migrations/20260516151053_InitialCreate.Designer.cs new file mode 100644 index 0000000..8473c70 --- /dev/null +++ b/Migrations/20260516151053_InitialCreate.Designer.cs @@ -0,0 +1,127 @@ +// +using System; +using AuthorBuddy.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AuthorBuddy.Web.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20260516151053_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.8"); + + modelBuilder.Entity("AuthorBuddy.Web.Data.DocumentMetaEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("file_path"); + + b.Property("FileType") + .HasColumnType("TEXT") + .HasColumnName("file_type"); + + b.Property("Hash") + .HasColumnType("TEXT"); + + b.Property("LastModified") + .HasColumnType("TEXT") + .HasColumnName("last_modified"); + + b.Property("ProjectId") + .HasColumnType("INTEGER") + .HasColumnName("project_id"); + + b.HasKey("Id"); + + b.ToTable("DocumentMeta", (string)null); + }); + + modelBuilder.Entity("AuthorBuddy.Web.Data.ProjectEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LastOpened") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RootPath") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("AuthorBuddy.Web.Data.SettingEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("key"); + + b.Property("ProjectId") + .HasColumnType("INTEGER") + .HasColumnName("project_id"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.ToTable("Settings", (string)null); + }); + + modelBuilder.Entity("AuthorBuddy.Web.Data.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IsCurrent") + .HasColumnType("INTEGER") + .HasColumnName("is_current"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20260516151053_InitialCreate.cs b/Migrations/20260516151053_InitialCreate.cs new file mode 100644 index 0000000..2a9f35c --- /dev/null +++ b/Migrations/20260516151053_InitialCreate.cs @@ -0,0 +1,93 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AuthorBuddy.Web.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DocumentMeta", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + project_id = table.Column(type: "INTEGER", nullable: true), + file_path = table.Column(type: "TEXT", nullable: false), + last_modified = table.Column(type: "TEXT", nullable: true), + Hash = table.Column(type: "TEXT", nullable: true), + file_type = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DocumentMeta", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Projects", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + RootPath = table.Column(type: "TEXT", nullable: false), + LastOpened = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Projects", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + key = table.Column(type: "TEXT", nullable: false), + value = table.Column(type: "TEXT", nullable: false), + user_id = table.Column(type: "INTEGER", nullable: true), + project_id = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + name = table.Column(type: "TEXT", nullable: false), + is_current = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DocumentMeta"); + + migrationBuilder.DropTable( + name: "Projects"); + + migrationBuilder.DropTable( + name: "Settings"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/Migrations/AppDbContextModelSnapshot.cs b/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 0000000..089a0a3 --- /dev/null +++ b/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,124 @@ +// +using System; +using AuthorBuddy.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AuthorBuddy.Web.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.8"); + + modelBuilder.Entity("AuthorBuddy.Web.Data.DocumentMetaEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("file_path"); + + b.Property("FileType") + .HasColumnType("TEXT") + .HasColumnName("file_type"); + + b.Property("Hash") + .HasColumnType("TEXT"); + + b.Property("LastModified") + .HasColumnType("TEXT") + .HasColumnName("last_modified"); + + b.Property("ProjectId") + .HasColumnType("INTEGER") + .HasColumnName("project_id"); + + b.HasKey("Id"); + + b.ToTable("DocumentMeta", (string)null); + }); + + modelBuilder.Entity("AuthorBuddy.Web.Data.ProjectEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LastOpened") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RootPath") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Projects", (string)null); + }); + + modelBuilder.Entity("AuthorBuddy.Web.Data.SettingEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("key"); + + b.Property("ProjectId") + .HasColumnType("INTEGER") + .HasColumnName("project_id"); + + b.Property("UserId") + .HasColumnType("INTEGER") + .HasColumnName("user_id"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("value"); + + b.HasKey("Id"); + + b.ToTable("Settings", (string)null); + }); + + modelBuilder.Entity("AuthorBuddy.Web.Data.UserEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IsCurrent") + .HasColumnType("INTEGER") + .HasColumnName("is_current"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("Users", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Program.cs b/Program.cs index d821f15..1e900a9 100644 --- a/Program.cs +++ b/Program.cs @@ -21,7 +21,13 @@ builder.Services.AddDbContextFactory(options => var app = builder.Build(); -AppDbContext.InitializeDatabase(Constants.SQLiteConnection); +AppDbContext.SetupVecExtension(Constants.SQLiteConnection); + +await using var db = await app.Services.GetRequiredService>().CreateDbContextAsync(); +await db.Database.MigrateAsync(); + +var settingsInit = app.Services.GetRequiredService(); +await settingsInit.InitializeAsync(); if (!app.Environment.IsDevelopment()) { diff --git a/Services/IOllamaService.cs b/Services/IOllamaService.cs index 6408792..954cac7 100644 --- a/Services/IOllamaService.cs +++ b/Services/IOllamaService.cs @@ -8,10 +8,6 @@ public interface IOllamaService { Task> GetLocalModelsAsync(); Task PullModelAsync(string modelName, IProgress progress); - //Task> GetEmbeddingAsync(string text); - //Task StreamStyleCheckAsync(string input); - //Task AnswerBasedOnFactsAsync(string question, string facts); - //Task QuickSpellCheckAsync(string text); + Task QuickSpellCheckAsync(string text); void Reconfigure(string ollamaUrl); - } diff --git a/Services/ISettingsService.cs b/Services/ISettingsService.cs index d853f81..761bbed 100644 --- a/Services/ISettingsService.cs +++ b/Services/ISettingsService.cs @@ -1,4 +1,6 @@ -namespace AuthorBuddy.Web.Services; +using AuthorBuddy.Web.Data; + +namespace AuthorBuddy.Web.Services; public interface ISettingsService { @@ -21,5 +23,12 @@ public interface ISettingsService Task SaveFactCheckTemplateAsync(string prompt); Task SaveSpellingPromptAsync(string prompt); + Task> GetUsersAsync(); + Task GetCurrentUserAsync(); + Task SetCurrentUserAsync(int userId); + Task CreateUserAsync(string name); + + int? CurrentProjectId { get; set; } + Task InitializeAsync(); } diff --git a/Services/OllamaService.cs b/Services/OllamaService.cs index fa49caf..b083082 100644 --- a/Services/OllamaService.cs +++ b/Services/OllamaService.cs @@ -1,15 +1,19 @@ using AuthorBuddy.Web.Models; using System.Text.Json; +using static System.Net.Mime.MediaTypeNames; namespace AuthorBuddy.Web.Services; public class OllamaService : IOllamaService { private readonly HttpClient _httpClient; + private readonly OllamaSettings _settings; private string _baseUrl = "http://localhost:11434"; - public OllamaService() + public OllamaService(OllamaSettings settings) { + _settings = settings; + _baseUrl = settings.OllamaUrl; _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(300) }; } @@ -49,6 +53,27 @@ public class OllamaService : IOllamaService } } + public async Task QuickSpellCheckAsync(string text) + { + return await Chat(_settings.SpellingModel, text, _settings.SpellingPrompt); + } + + public async Task StreamStyleCheckAsync(string text) + { + var systemPrompt = _settings.LektorSystemPrompt; + return await Chat(_settings.StyleModel, text, systemPrompt); + + } + + public async Task AnswerBasedOnFactsAsync(string question, string facts) + { + var prompt = _settings.GetFactCheckPrompt(question, facts); + + return await Chat(_settings.EmbedModel, prompt); + } + + + public async Task Chat(string model, string userMessage, string? systemPrompt = null) { try @@ -57,6 +82,7 @@ public class OllamaService : IOllamaService { model = model, prompt = userMessage, + system = systemPrompt, stream = false }; diff --git a/Services/SettingsService.cs b/Services/SettingsService.cs index 649b78e..8d37810 100644 --- a/Services/SettingsService.cs +++ b/Services/SettingsService.cs @@ -17,6 +17,8 @@ public class SettingsService : ISettingsService private readonly IDbContextFactory _contextFactory; private readonly OllamaSettings _ollamaConfig; + private int? _currentUserId; + private int? _currentProjectId; public SettingsService(IDbContextFactory contextFactory, OllamaSettings ollamaConfig) { @@ -24,35 +26,69 @@ public class SettingsService : ISettingsService _ollamaConfig = ollamaConfig; } - private async Task GetAsync(string key) + public int? CurrentProjectId + { + get => _currentProjectId; + set => _currentProjectId = value; + } + + private async Task GetSettingAsync(string key, int? userId, int? projectId) { await using var context = await _contextFactory.CreateDbContextAsync(); - var setting = await context.Settings.FindAsync(key); + + var matches = context.Settings.Where(s => + s.Key == key && + (s.UserId == userId || s.UserId == null) && + (s.ProjectId == projectId || s.ProjectId == null)); + + var setting = await matches + .OrderByDescending(s => s.UserId != null) + .ThenByDescending(s => s.ProjectId != null) + .FirstOrDefaultAsync(); + return setting?.Value; } + private async Task GetAsync(string key) + { + return await GetSettingAsync(key, _currentUserId, _currentProjectId); + } + + private async Task SetAsync(string key, string value) + { + await using var context = await _contextFactory.CreateDbContextAsync(); + + var existing = await context.Settings + .Where(s => s.Key == key && s.UserId == _currentUserId && s.ProjectId == _currentProjectId) + .FirstOrDefaultAsync(); + + if (existing != null) + { + existing.Value = value; + } + else + { + context.Settings.Add(new SettingEntity + { + Key = key, + Value = value, + UserId = _currentUserId, + ProjectId = _currentProjectId + }); + } + + await context.SaveChangesAsync(); + } + public Task GetOllamaUrlAsync() => GetAsync(KeyOllamaUrl); public Task GetRagModelAsync() => GetAsync(KeyRagModel); public Task GetStyleModelAsync() => GetAsync(KeyStyleModel); - public Task GetLektorSystemPromptAsync() => GetAsync(KeyLektorPrompt); public Task GetFactCheckTemplateAsync() => GetAsync(KeyFactCheckTemplate); public Task GetSpellingPromptAsync() => GetAsync(KeySpellingPrompt); - public Task GetSpellingModelAsync() => GetAsync(KeySpellingModel); public Task GetThemeAsync() => GetAsync(KeyTheme); - private async Task SetAsync(string key, string value) - { - await using var context = await _contextFactory.CreateDbContextAsync(); - var existing = await context.Settings.FindAsync(key); - if (existing != null) - existing.Value = value; - else - context.Settings.Add(new SettingEntity { Key = key, Value = value }); - await context.SaveChangesAsync(); - } - public async Task SaveOllamaUrlAsync(string url) { await SetAsync(KeyOllamaUrl, url); @@ -82,6 +118,7 @@ public class SettingsService : ISettingsService await SetAsync(KeyFactCheckTemplate, prompt); _ollamaConfig.FactCheckTemplate = prompt; } + public async Task SaveSpellingPromptAsync(string prompt) { await SetAsync(KeySpellingPrompt, prompt); @@ -97,10 +134,56 @@ public class SettingsService : ISettingsService public Task SaveThemeAsync(string theme) => SetAsync(KeyTheme, theme); + public async Task> GetUsersAsync() + { + await using var context = await _contextFactory.CreateDbContextAsync(); + return await context.Users.ToListAsync(); + } + + public async Task GetCurrentUserAsync() + { + await using var context = await _contextFactory.CreateDbContextAsync(); + var user = await context.Users.FirstOrDefaultAsync(u => u.IsCurrent); + return user ?? await context.Users.FirstAsync(); + } + + public async Task SetCurrentUserAsync(int userId) + { + await using var context = await _contextFactory.CreateDbContextAsync(); + var users = await context.Users.ToListAsync(); + foreach (var u in users) + u.IsCurrent = u.Id == userId; + await context.SaveChangesAsync(); + _currentUserId = userId; + } + + public async Task CreateUserAsync(string name) + { + await using var context = await _contextFactory.CreateDbContextAsync(); + var user = new UserEntity { Name = name }; + context.Users.Add(user); + await context.SaveChangesAsync(); + return user; + } + public async Task InitializeAsync() { await using var context = await _contextFactory.CreateDbContextAsync(); + var userExists = await context.Users.AnyAsync(); + if (!userExists) + { + var defaultUser = new UserEntity { Name = "Standardbenutzer", IsCurrent = true }; + context.Users.Add(defaultUser); + await context.SaveChangesAsync(); + _currentUserId = defaultUser.Id; + } + else + { + var current = await context.Users.FirstOrDefaultAsync(u => u.IsCurrent); + _currentUserId = current?.Id ?? (await context.Users.FirstAsync()).Id; + } + var entries = new (string Key, string Default)[] { (KeyOllamaUrl, _ollamaConfig.OllamaUrl), @@ -115,7 +198,10 @@ public class SettingsService : ISettingsService foreach (var entry in entries) { - var existing = await context.Settings.FindAsync(entry.Key); + var existing = await context.Settings + .Where(s => s.Key == entry.Key && s.UserId == _currentUserId && s.ProjectId == null) + .FirstOrDefaultAsync(); + if (existing != null) { var val = existing.Value; @@ -130,7 +216,13 @@ public class SettingsService : ISettingsService } else { - context.Settings.Add(new SettingEntity { Key = entry.Key, Value = entry.Default }); + context.Settings.Add(new SettingEntity + { + Key = entry.Key, + Value = entry.Default, + UserId = _currentUserId, + ProjectId = null + }); } } diff --git a/author_brain.db b/author_brain.db index 6c9e6fb0c535946f1e14bd7a0c624854899deba1..9345e48d312d1954dc307f00e00e4a097a9a42a6 100644 GIT binary patch delta 2088 zcmb7FO>7%Q6rSwv@wi368h5En!QNZ~}u1x^Tw3$yDuv2l`;mAqQdd+(d~ zeeb=QyAPT9AA@9*AEJbUgxJs-Kp zc$)u}-C_Qw|Dop}-T%T>Gs1`w1Oe7pbmc})U9G6)iv2&&RZf@oVbqD4TiI=>o1J-UM1*$Yx0PJ=I8s$2az^V^up_WkF21d1^&Y#$ z_PV#l7MVlnY|Y!vHrWb1CELTOC$f!qm#JpeyiGS%Eb2)`U+gPR-Fgy(J33m6rUd&eWq}I!-u5^BTx|z02wU*!Mirb0m$4{huTrn)#HLC+| zYB@DiI-Yor5YOa`YuZh%i+fwQC8ctpS%+RWtiD+~=%AKd##NpXLLpdB5V>k(=Zt)5 zS-VwMbgfvZENK#}9`W14( zkZk{hOL`&driC{{X2Um7I}$V_9l7i_A{-+~608U89_n_A6|)1sI`87wIzi}&$q|5x)HwsmI?!W){z8wp`ti?bz~i6>Vf$ocSx5<- zeY}6xz|FUueKhDJchOJ8_j@$)0;It5q&PVf5Q70}21~*4lo*y~$7d#`+0gU_Q4EWs zmuv^o4nR93=sP40LrQ+e3KE0Tj1-i_;8Z4B&~#17EtFM7S0!;=9Djwk!*&7MC1F1x zJVeRdNm0#)6Q5x{+Ya<2`U-uFO6a<8$osBmd#k^%>EVqDmI1SMi38^L+(X{L3uO$oXEwO5zv!evXov&FTu#X=nMz5` z<;aa=O}v^bt!q=^yjIXKMFWX|w!QRCGP<^l9X2&S`J96WfkTh7vJcU=zXWOUJT*)5 lGG4`eOS?UQ_J|0(=;<@i2?89szzb_idF_T;sOopr^1r7>KvDnz delta 1508 zcmZux-)|yC9N+0Iu)r?U##HX~Fxxbw5pwCZ7Fgz=|vLU!cdTf#oa|E zG2y6sF-8;5dFq?mmrKt0AiiC4G3kF`d{pmVP0pu2_~L`Za;s1}$?nd4zu*0SKcCNh zXYM_N_r8H&y*lG%7)GFvJ-7!;s|#Kxaz7;a9y0<*7&PlU7ykBr&ZmVZ-X~t@?RZk| zFFE2~>Ca3H9PHiT$%S_d@MO++g9tn#n13Az-aw>!XBrrZEJW6)WDCVGmF-v$n5p}w|R!{S~W zt7=78+8e3Dfq`|S@MgAPZ>LdMYnxR~UvHPoox)i7N_6E`I4Xr>x5Q{7CB;&4DH4q) zS6AbMTLGX823^o%f1;olz<}EpNI>5*9DmNB4EhBs0aP{1Y(fTpTSBM4zEY|WISVRqeqgb5_~4xFZ|f@iGK|^F p5pwW4OaLu3pifDUv6*@ahTShf>B