WikiSage -- Your Tiddlywiki AI Companion

Sorry I was wrong, core AI plugin draft already have this standard, just following it will be fine

with tags: $:/tags/AI/CompletionServer and \procedure json-prompt() and \procedure completion-callback()

And there is already a core comment plugin Why is comment plugin not mentioned in the official documentation site , so I think making a AI comment plugin is pretty easy now, based on core plugins.

I’m pushing this forward by
AI tools more server by linonetwo · Pull Request #8966 · TiddlyWiki/TiddlyWiki5 · GitHub
and
[IDEA] SetTimeout / SetInterval / SetAlarmClock widget · Issue #8967 · TiddlyWiki/TiddlyWiki5 · GitHub

Hi @well-noted , is this possible in WikiSage?

It would be cool to use a temp-tiddler that is not saved to store the API-Key…
BTW I am working on a tiny plugin to encrypt the apikey so that only the owner of the wiki can use it.

Hmm… I don’t know if that will work, @JanJo I’ve never tried to transclude that way. Why don’t you try and let me know? It’s a good idea :slight_smile:

1 Like

@JanJo, PS I have a hacky solution for integrating Gemini now :slight_smile:

If you’d like to give it a try (preview before the repackage), replace the contents of the widget.js with $__plugins_NoteStreams_WikiSage_widget.js.tid (130.4 KB) and then make sure you have your API key in $:/plugins/NoteStreams/WikiSage/gemini-api-key

Add the model you want to use to the list and it should work :slight_smile: The model I have working is gemini-2.5-flash-preview-04-17

Currently only supports chat, no tool use, but I will implement that in the actual release if possible. I don’t currently know if Gemini will allow tool use, though I do see that function-calling is allowed, so that should work.

1 Like

See TiddlyTools/Filters/encrypt.js which defines encrypt[key] and decrypt[key] filter operators.

To take user input and encrypt it, you could get both an APIKey value as well as an encryption key value that you would use as a “password” and then use the encrypt[...] filter to generate a JSON object that encodes the APIKey in encrypted form that can be stored in a tiddler (e.g. “MyAPIKey”).

Later on, you could then use that stored JSON object plus the same “password” value with the decrypt[...] filter to retrieve the unencrypted APIKey value and then reference {{$:/temp/APIKey!!key}} to access your OpenAI account.

Something like this:

APIKey: <$edit-text tiddler="$:/temp/APIKey" field="key"/>
Password: <$edit-text tiddler="$:/temp/APIKey" field="password"/>
<$button> save key
   <$action-setfield $tiddler="MyAPIKey"
      text={{{ [{$:/temp/APIKey!!key}encrypt{$:/temp/APIKey!!password}] }}}/>
</$button>
<$button> get key
   <$action-setfield $tiddler="$:/temp/APIKey"
      key={{{ [{MyAPIKey}decrypt{$:/temp/APIKey!!password}] }}}/>
</$button>

Note that by default $:/temp tiddlers are automatically discarded when the file is saved, so only the resulting “MyAPIKey” tiddler containing the encrypted JSON object is saved in your TiddlyWiki file.

Note also that for added security, you could use a <$password> widget for entering the encryption key, like this:

APIKey: <$edit-text tiddler="$:/temp/APIKey" field="key"/>
Password: <$password name="OpenAPIpassword"/>
<$button> save key
   <$action-setfield $tiddler="MyAPIKey"
      text={{{ [{$:/temp/APIKey!!key}encrypt:password[OpenAPIpassword]] }}}/>
</$button>
<$button> get key
   <$action-setfield $tiddler="$:/temp/APIKey"
      key={{{ [{MyAPIKey}decrypt:password[OpenAPIpassword]] }}}/>
</$button>

In this way, the password you enter is NEVER stored in a tiddler (not even a $:/temp tiddler), but is instead stored directly in your browser’s LocalStorage, which is used as the TiddlyWiki “Password Vault”.

enjoy,
-e

2 Likes

I also was working on a way to use the browserstorage to encrypt the tiddler. I guess @EricShulman’s solution is better.

I think the best way would be to directly store all APIKeys in temporary tiddlers and use @EricShulman’s mechanism to set it to the TIddler…
The password could be the same for all APIKeys I guess.

Addendum:

When using TiddlyTools decrypt[...] filter, if the “password” you provide is incorrect the filter returns the text:

CORRUPT: ccm: tag doesn't match

(this is the value returned from the underlying Javascript sjcl.decrypt() library function)

So, when fetching the saved key from the encrypted JSON, if that text is returned, you will want to set the $:/temp/APIKey!!key value to blank, like this:

<$button> get key
   <$action-setfield $tiddler="$:/temp/APIKey"
      key={{{ [{MyAPIKey}decrypt{$:/temp/APIKey!!password}!match[CORRUPT: ccm: tag doesn't match]] }}}/>
</$button>

-e

I just installed it… but don’t I need the configtab to enter the api-key for gemini?

You don’t need the configtab, you can just edit the file directly :slight_smile:

But this should be far more helpful for you, and it’s packaged all pretty so you should be able to use the config tab to enter your API:

$__plugins_NoteStreams_WikiSage.tid (1.4 MB)

I’ve also included a “Toggles” tab that allows you to toggle on and off certain features.

Let me know what you think :slight_smile:

1 Like

This is a really great plugin! Thank you alot!
I have a question about the instruction in the config tab.
It seems that it has no effect on my prompts.
My instruction is something like “read my tiddlers before answering”
But if I ask a question about a topic of my wiki. The answer has absolutely nothing to do with my wiki.
How to force gpt to know my content by default?
Is the instruction added to the messages array as system prompt?

1 Like

Ok, it seems to work with this instruction:
“Always Search for relevant tiddlers and Extract their content.”

2 Likes

A preview of one of the many new features that will be in the new release:

vivaldi_ZxXtgRPdmC

1 Like

@Michael_Kohlhaas, you may appreciate one of the upcoming release features:

Which allows you to add multiple tiddlers which you would specifically like to reference and instructions, in addition to the standard conversation.

Eagle-eyed viewers will notice that it also includes an export-conversation feature, which is going to be standard in all the future widgets.

2 Likes

Hi @well-noted, thank you for the update. I finally had the time to test it and it is great to have the free-option of gemini in it.
Alas i found out the using it in my production-wikis is still a problem, because at the moment the API-Keys are saved, when I save on the go.
Alas the transclusion-workaround does not work. So could you please make the plugin use a temporary tiddler to store the key… and perhaps the mechanism suggested by @EricShulman to insert it form an encrypted value?

In the version of the plugin I installed, I can use the new gemini-API only in the coding wizard. Is there a version where i can use it with the normal interface.
It would be cool to be able to use the excise function on the results.

Yes, you should be able to use the normal interface now, but the next released version should work out-of-the-box

Can you explain what isn’t working about the gemini models in the normal interface? The model is in the model-list, but it does not work?

If I can think of a way to have this be a mode-switching toggle, I will do so. I think standard production mode it makes most sense to have it stored in a non-temporary tiddler – if there’s some way to have “use temporary tiddler instead” in the settings, I will do so.

1 Like

In the dropdown of $:/plugins/NoteStreams/WikiSage/WikiSage-ui I just have the option of gemini 2.5 flash and 3 openai llms. (Not like in the ai-coder) If I choose gemini it tells me to enter an open-ai-key - though the gemini-key is present and working in the ai coder.

I was not able to find the beautifull interface shown here in my version.