Closed koppor closed 2 months ago
I'm not sure how to code this properly. This will probably break some symmetry and used practice, but yes, the issue is right.
Can I make org.jabref.preferences.JabRefPreferences#getAiPreferences
public?
I'm not sure how to code this properly. This will probably break some symmetry and used practice, but yes, the issue is right.
Maybe, the other places need to be changed "accordingly" (e.g., proxy password, ...). I think, however, that it is OK for JabRef users with proxy passwords that JabRef asks for the password right at the start. For API keys, I am not that sure...
With your changes, an example can be shown how it will work.
Can I make
org.jabref.preferences.JabRefPreferences#getAiPreferences
public?
Yes. This will lead to another method signature in PreferenceServcid
, whcih is OK.
Maybe "Future" helps?
Okay, I think I managed to do this in a recent push
No, see output of gradlew run
:
$ ./gradlew run
> Configure project :
Project : => 'org.jabref' Java module
> Task :run
WARNING: Using incubator modules: jdk.incubator.vector
Messages are not initialized before accessing key: Display help on command line options
2024-08-06 17:00:16 [JavaFX Application Thread] org.jabref.gui.theme.ThemeManager.addStylesheetToWatchlist()
INFO: Watching css C:\git-repositories\jabref-all\jabref\build\resources\main\org\jabref\gui\Base.css for live updates
2024-08-06 17:00:16 [JavaFX Application Thread] org.jabref.gui.theme.ThemeManager.updateThemeSettings()
INFO: Not updating theme because it hasn't changed
2024-08-06 17:00:16 [JavaFX Application Thread] org.jabref.gui.theme.ThemeManager.updateThemeSettings()
INFO: Theme set to Theme{type=DEFAULT, name=''} with base css StyleSheet{file:/C:/git-repositories/jabref-all/jabref/build/resources/main/org/jabref/gui/Base.css}
2024-08-06 17:00:16 [JavaFX Application Thread] org.jabref.preferences.JabRefPreferences.getApiKeyForAiProvider()
WARN: JabRef could not open keyring for retrieving OpenAI API token: com.github.javakeyring.PasswordAccessException: Error code 1168
at java.keyring@1.0.4/com.github.javakeyring.internal.windows.WinCredentialStoreBackend.getPassword(WinCredentialStoreBackend.java:61)
at java.keyring@1.0.4/com.github.javakeyring.Keyring.getPassword(Keyring.java:90)
at org.jabref@100.0.0/org.jabref.preferences.JabRefPreferences.getApiKeyForAiProvider(JabRefPreferences.java:2855)
at org.jabref@100.0.0/org.jabref.preferences.JabRefPreferences.getAiPreferences(JabRefPreferences.java:2795)
at org.jabref@100.0.0/org.jabref.gui.JabRefGUI.initialize(JabRefGUI.java:159)
at org.jabref@100.0.0/org.jabref.gui.JabRefGUI.start(JabRefGUI.java:90)
at javafx.graphics@22.0.2/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at javafx.graphics@22.0.2/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at javafx.graphics@22.0.2/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics@22.0.2/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1583)
2024-08-06 17:00:16 [pool-2-thread-1] org.jabref.logic.ai.models.EmbeddingModel.rebuild()
INFO: Downloading embedding model...
Loading: 100% |========================================|
2024-08-06 17:00:16 [pool-2-thread-1] ai.djl.pytorch.jni.LibUtils.downloadPyTorch()
WARN: No matching cuda flavor for win-x86_64 found: cu065.
2024-08-06 17:00:17 [pool-2-thread-1] ai.djl.pytorch.engine.PtEngine.newInstance()
INFO: PyTorch graph executor optimizer is enabled, this may impact your inference latency and throughput. See: https://docs.djl.ai/docs/development/inference_performance_optimization.html#graph-executor-optimization
2024-08-06 17:00:17 [pool-2-thread-1] ai.djl.pytorch.engine.PtEngine.newInstance()
INFO: Number of inter-op threads is 24
2024-08-06 17:00:17 [pool-2-thread-1] ai.djl.pytorch.engine.PtEngine.newInstance()
INFO: Number of intra-op threads is 12
2024-08-06 17:00:17 [pool-2-thread-1] ai.djl.util.Platform.detectPlatform()
INFO: Found matching platform from: jar:file:///C:/Users/koppor/.gradle/caches/modules-2/files-2.1/ai.djl.huggingface/tokenizers/0.29.0/edd38326d16523f2b8c2b1e360b896e7ae48a1fa/tokenizers-0.29.0.jar!/native/lib/tokenizers.properties
2024-08-06 17:00:17 [JavaFX Application Thread] org.jabref.gui.StateManager.setActiveDatabase()
INFO: No open database detected
2024-08-06 17:00:18 [pool-2-thread-2] org.jabref.gui.JabRefDialogService.notify()
INFO: Opening: 'C:\Users\koppor\OneDrive\Projects\JabRef-AI\Chocolate.bib'
2024-08-06 17:00:18 [JavaFX Application Thread] sun.util.logging.internal.LoggingProviderImpl$JULWrapper.log()
WARN: Resource "" not found.
2024-08-06 17:00:19 [JavaFX Application Thread] sun.util.logging.internal.LoggingProviderImpl$JULWrapper.log()
WARN: Resource "" not found.
2024-08-06 17:00:19 [JavaFX Application Thread] org.jabref.logic.ai.models.EmbeddingModel.lambda$startRebuildingTask$0()
INFO: Embedding model was successfully downloaded
2024-08-06 17:00:19 [JavaFX Application Thread] org.apache.lucene.internal.vectorization.PanamaVectorizationProvider.<init>()
INFO: Java vector incubator API enabled; uses preferredBitSize=256; FMA enabled
Are you sure you started JabRef without AI-enabled?
I highlight important terms of my issue description:
I try TL;DR:
If this is too difficult to implement, we can postpone to the famous week 12.
Ah, I see. I just implemented it for:
And after that the key will be fetched
As I understand, we should fetch the key ONLY when we start chatting or summarizing?
As I understand, we should fetch the key ONLY when we start chatting or summarizing?
Yes.
For the preferences, it is difficult. A "perfect" solution would be follwowing:
Assumption: Password field is write-only
There is no (!) eye icon - thus I cannot read from the field:
As a consequence, the field is write only.
Question: Should the user know if (s)he entered anything?
After the user changed the text field, the new key is stored in the key store.
No need to read the api key ever in the preferences.
Note that there is something reading the the AI Preferences - and thus the key:
> Task :run
WARNING: Using incubator modules: jdk.incubator.vector
Messages are not initialized before accessing key: Display help on command line options
2024-08-07 06:27:15 [JavaFX Application Thread] org.jabref.gui.theme.ThemeManager.addStylesheetToWatchlist()
INFO: Watching css /home/vagrant/jabref/build/resources/main/org/jabref/gui/Base.css for live updates
2024-08-07 06:27:15 [JavaFX Application Thread] org.jabref.gui.theme.ThemeManager.updateThemeSettings()
INFO: Not updating theme because it hasn't changed
2024-08-07 06:27:15 [JavaFX Application Thread] org.jabref.gui.theme.ThemeManager.updateThemeSettings()
INFO: Theme set to Theme{type=DEFAULT, name=''} with base css StyleSheet{file:/home/vagrant/jabref/build/resources/main/org/jabref/gui/Base.css}
2024-08-07 06:27:15 [JavaFX Application Thread] org.freedesktop.dbus.connections.transports.TransportBuilder.build()
INFO: Using transport dbus-java-transport-native-unixsocket to connect to unix:path=/run/user/1000/bus
2024-08-07 06:27:16 [JavaFX Application Thread] org.freedesktop.secret.handlers.SignalHandler.await()
INFO: Await signal Prompt.Completed(/org/freedesktop/secrets/prompt/u1) within 120 seconds.
2024-08-07 06:27:20 [DBus-Signal-Receiver-1] org.freedesktop.secret.handlers.SignalHandler.handle()
INFO: Received signal Service.CollectionChanged: /org/freedesktop/secrets/collection/login
2024-08-07 06:27:20 [DBus-Signal-Receiver-1] org.freedesktop.secret.handlers.SignalHandler.handle()
INFO: Received signal Prompt.Completed(/org/freedesktop/secrets/prompt/u1): {dismissed: false, result: [[/org/freedesktop/secrets/aliases/default]]}
2024-08-07 06:27:20 [JavaFX Application Thread] org.freedesktop.dbus.connections.transports.TransportBuilder.build()
INFO: Using transport dbus-java-transport-native-unixsocket to connect to unix:path=/run/user/1000/bus
2024-08-07 06:27:20 [JavaFX Application Thread] org.jabref.preferences.JabRefPreferences.getApiKeyForAiProvider()
WARN: JabRef could not open keyring for retrieving OpenAI API token: com.github.javakeyring.PasswordAccessException: No stored credentials match org.jabref.ai account: apitoken-MISTRAL_AI
at java.keyring@1.0.4/com.github.javakeyring.internal.freedesktop.FreedesktopKeyringBackend.throwNoExistingCredentialException(FreedesktopKeyringBackend.java:161)
at java.keyring@1.0.4/com.github.javakeyring.internal.freedesktop.FreedesktopKeyringBackend.getPassword(FreedesktopKeyringBackend.java:91)
at java.keyring@1.0.4/com.github.javakeyring.Keyring.getPassword(Keyring.java:90)
at org.jabref@100.0.0/org.jabref.preferences.JabRefPreferences.getApiKeyForAiProvider(JabRefPreferences.java:2855)
at org.jabref@100.0.0/org.jabref.preferences.JabRefPreferences.getAiPreferences(JabRefPreferences.java:2794)
at org.jabref@100.0.0/org.jabref.gui.JabRefGUI.initialize(JabRefGUI.java:159)
at org.jabref@100.0.0/org.jabref.gui.JabRefGUI.start(JabRefGUI.java:90)
at javafx.graphics@22.0.2/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at javafx.graphics@22.0.2/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at javafx.graphics@22.0.2/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at javafx.graphics@22.0.2/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$10(GtkApplication.java:264)
at java.base/java.lang.Thread.run(Thread.java:1583)
2024-08-07 06:27:20 [JavaFX Application Thread] org.freedesktop.dbus.connections.transports.TransportBuilder.build()
INFO: Using transport dbus-java-transport-native-unixsocket to connect to unix:path=/run/user/1000/bus
2024-08-07 06:27:20 [JavaFX Application Thread] org.jabref.preferences.JabRefPreferences.getApiKeyForAiProvider()
WARN: JabRef could not open keyring for retrieving OpenAI API token: com.github.javakeyring.PasswordAccessException: No stored credentials match org.jabref.ai account: apitoken-HUGGING_FACE
at java.keyring@1.0.4/com.github.javakeyring.internal.freedesktop.FreedesktopKeyringBackend.throwNoExistingCredentialException(FreedesktopKeyringBackend.java:161)
at java.keyring@1.0.4/com.github.javakeyring.internal.freedesktop.FreedesktopKeyringBackend.getPassword(FreedesktopKeyringBackend.java:91)
at java.keyring@1.0.4/com.github.javakeyring.Keyring.getPassword(Keyring.java:90)
at org.jabref@100.0.0/org.jabref.preferences.JabRefPreferences.getApiKeyForAiProvider(JabRefPreferences.java:2855)
at org.jabref@100.0.0/org.jabref.preferences.JabRefPreferences.getAiPreferences(JabRefPreferences.java:2795)
at org.jabref@100.0.0/org.jabref.gui.JabRefGUI.initialize(JabRefGUI.java:159)
at org.jabref@100.0.0/org.jabref.gui.JabRefGUI.start(JabRefGUI.java:90)
at javafx.graphics@22.0.2/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at javafx.graphics@22.0.2/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at javafx.graphics@22.0.2/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at javafx.graphics@22.0.2/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at javafx.graphics@22.0.2/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$10(GtkApplication.java:264)
at java.base/java.lang.Thread.run(Thread.java:1583)
2024-08-07 06:27:21 [pool-2-thread-1] org.jabref.logic.ai.models.EmbeddingModel.rebuild()
See my comment https://github.com/JabRef/jabref/commit/1d4c383ddc31c4d2423949da51f288b5a81e4901 on a possible code-based solution.
Hope I managed to do this in a recent push
I commented at https://github.com/JabRef/jabref/pull/11430#pullrequestreview-2225753481 - please refine the code.
I took this approach: I mark unloaded keys as empty strings. If the string is empty, then it will be retrieved from keyring. I think, this is okay?
(You should see a message "InAnYan referenced this issue", above this comment)
About factoring out fields: I wonder, if it's really needed. Currently I only see one purpose - grouping. If it had more complex logic..
Actually, I understood. It would be better to have a separate class for API keys in case there will be more of them. They should be stored in a Map<AiProvider, String>
, or something like that
Actually, I understood. It would be better to have a separate class for API keys in case there will be more of them.
Yes!
They should be stored in a
Map<AiProvider, String>
, or something like that
Yes. The enum org.jabref.preferences.ai.AiProvider
is really good.
The label
can directly be used as last part of the item name in the java key store.
I wonder, Oliver, if we can make a separate issue for "Refactor support of multiple AI providers", because not only API key is associated with an AI provider.
For now we have a simple fix.
What if I make that issue and close this one (close this - because API token is fetched later)
Go ahead with creating a new issue and closing this (with a reference to the new isssue)
There still was a call to rebuild
reading the API key in org.jabref.logic.ai.models.JabRefChatLanguageModel#JabRefChatLanguageModel. Removed at 400d83e7e82e1b716ccb3b16f64aa9bb.
JabRef uses Java Key Ring to connect to password stores.
org.jabref.preferences.JabRefPreferences#getAiPreferences
access that key store when creating the AI Chat tab. This leads to following startup error output:When opening preferences, the key is there.
When using Gnome, on startup, one will be asked to open the key store. This is not necessary. It is necessary when interacting with the AI.
Please postpone the call to
org.jabref.preferences.JabRefPreferences#getAiApiTokenFromKeyring
to the latest point in time (and store the key internally once retrieved). (OK, one also has to take care if they key is changed by the user)