mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-07-31 00:02:51 +00:00
Refactor procedures and functions to be global for reuse
This commit is contained in:
parent
58f96e779a
commit
ea595dfe2f
@ -1,7 +1,7 @@
|
||||
title: $:/plugins/tiddlywiki/ai-tools/globals
|
||||
tags: $:/tags/Global
|
||||
|
||||
\function default-llm-completion-server()
|
||||
\function ai-tools-default-llm-completion-server()
|
||||
[all[shadows+tiddlers]tag[$:/tags/AI/CompletionServer]sort[caption]first[]]
|
||||
\end
|
||||
|
||||
@ -10,16 +10,16 @@ Action procedure to retrieve an LLM completion, given the following parameters:
|
||||
conversationTitle - Title of the tiddler containing the conversation
|
||||
resultTitlePrefix - Prefix of the tiddler to be used for saving the result. If the tiddler already exists then a number will be added repeatedly until the resulting title is unique
|
||||
resultTags - Tags to be applied to the result tiddler
|
||||
statusTitle - Optional title of a tiddler to which the status of the request will be bound: "pending", "complete", "error"
|
||||
ai-tools-status-title - Optional title of a tiddler to which the status of the request will be bound: "pending", "complete", "error"
|
||||
completionServer - Optional URL of server
|
||||
-->
|
||||
\procedure get-llm-completion(conversationTitle,resultTitlePrefix,resultTags,statusTitle,completionServer)
|
||||
\procedure ai-tools-get-llm-completion(conversationTitle,resultTitlePrefix,resultTags,ai-tools-status-title,completionServer)
|
||||
<$let
|
||||
completionServer={{{ [<completionServer>!is[blank]else<default-llm-completion-server>] }}}
|
||||
completionServer={{{ [<completionServer>!is[blank]else<ai-tools-default-llm-completion-server>] }}}
|
||||
>
|
||||
<$importvariables filter="[<completionServer>]">
|
||||
<$wikify name="json" text=<<json-prompt>>>
|
||||
<$action-log message="get-llm-completion"/>
|
||||
<$action-log message="ai-tools-get-llm-completion"/>
|
||||
<$action-log/>
|
||||
<$action-sendmessage
|
||||
$message="tm-http-request"
|
||||
@ -29,11 +29,176 @@ completionServer - Optional URL of server
|
||||
bearer-auth-token-from-store="openai-secret-key"
|
||||
method="POST"
|
||||
oncompletion=<<completion-callback>>
|
||||
bind-status=<<statusTitle>>
|
||||
bind-status=<<ai-tools-status-title>>
|
||||
var-resultTitlePrefix=<<resultTitlePrefix>>
|
||||
var-resultTags=<<resultTags>>
|
||||
/>
|
||||
</$wikify>
|
||||
</$importvariables>
|
||||
</$let>
|
||||
\end get-llm-completion
|
||||
\end ai-tools-get-llm-completion
|
||||
|
||||
<!--
|
||||
-->
|
||||
\function ai-tools-status-title()
|
||||
[<currentTiddler>addprefix[$:/temp/ai-tools/status/]]
|
||||
\end ai-tools-status-title
|
||||
|
||||
<!--
|
||||
Procedure to display a message from an AI conversation. Current tiddler is the conversation tiddler
|
||||
-->
|
||||
\procedure ai-tools-message(tiddler,field,role,makeLink:"yes")
|
||||
<$qualify
|
||||
name="state"
|
||||
title={{{ [[$:/state/ai-tools-message-state/]addsuffix<tiddler>] }}}
|
||||
>
|
||||
<$let
|
||||
editStateTiddler={{{ [<state>addsuffix[-edit-state]] }}}
|
||||
editState={{{ [<editStateTiddler>get[text]else[view]] }}}
|
||||
>
|
||||
<div class={{{ ai-tools-message [<role>addprefix[ai-tools-message-role-]] +[join[ ]] }}}>
|
||||
<div class="ai-tools-message-toolbar">
|
||||
<div class="ai-tools-message-toolbar-left">
|
||||
<$genesis $type={{{ [<makeLink>match[yes]then[$link]else[span]] }}} to=<<tiddler>>>
|
||||
<$text text=<<role>>/>
|
||||
</$genesis>
|
||||
</div>
|
||||
<div class="ai-tools-message-toolbar-left">
|
||||
<%if [<editState>!match[edit]] %>
|
||||
<$button class="ai-tools-message-toolbar-button">
|
||||
<$action-setfield $tiddler=<<editStateTiddler>> text="edit"/>
|
||||
edit
|
||||
</$button>
|
||||
<%endif%>
|
||||
<%if [<editState>!match[view]] %>
|
||||
<$button class="ai-tools-message-toolbar-button">
|
||||
<$action-setfield $tiddler=<<editStateTiddler>> text="view"/>
|
||||
view
|
||||
</$button>
|
||||
<%endif%>
|
||||
<$button class="ai-tools-message-toolbar-button">
|
||||
<$action-sendmessage $message="tm-copy-to-clipboard" $param={{{ [<tiddler>get<field>else[]] }}}/>
|
||||
copy
|
||||
</$button>
|
||||
<$button class="ai-tools-message-toolbar-button">
|
||||
<$action-deletetiddler $tiddler=<<tiddler>>/>
|
||||
delete
|
||||
</$button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ai-tools-message-body">
|
||||
<%if [<editState>match[view]] %>
|
||||
<$transclude $tiddler=<<tiddler>> $field=<<field>> $mode="block"/>
|
||||
<%else%>
|
||||
<$edit-text tiddler=<<tiddler>> field=<<field>> tag="textarea" class="tc-edit-texteditor"/>
|
||||
<%endif%>
|
||||
<%if [<tiddler>get[image]else[]!match[]] %>
|
||||
<$image source={{{ [<tiddler>get[image]] }}}/>
|
||||
<%endif%>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
</$qualify>
|
||||
\end ai-tools-message
|
||||
|
||||
<!--
|
||||
Action procedure to get the next response from the LLM
|
||||
-->
|
||||
\procedure ai-tools-action-get-response()
|
||||
<$let
|
||||
resultTitlePrefix={{{ [<currentTiddler>addsuffix[ - Prompt]] }}}
|
||||
resultTags={{{ [<currentTiddler>format:titlelist[]] }}}
|
||||
>
|
||||
<$action-createtiddler
|
||||
$basetitle=<<resultTitlePrefix>>
|
||||
tags=<<resultTags>>
|
||||
type="text/markdown"
|
||||
role="user"
|
||||
text={{!!current-response-text}}
|
||||
image={{!!current-response-image}}
|
||||
>
|
||||
<$action-deletefield $tiddler=<<currentTiddler>> $field="current-response-text"/>
|
||||
<$action-deletefield $tiddler=<<currentTiddler>> $field="current-response-image"/>
|
||||
<$transclude
|
||||
$variable="ai-tools-get-llm-completion"
|
||||
conversationTitle=<<currentTiddler>>
|
||||
completionServer={{!!completion-server}}
|
||||
resultTitlePrefix=<<resultTitlePrefix>>
|
||||
resultTags=<<resultTags>>
|
||||
ai-tools-status-title=<<ai-tools-status-title>>
|
||||
/>
|
||||
</$action-createtiddler>
|
||||
</$let>
|
||||
\end ai-tools-action-get-response
|
||||
|
||||
\procedure ai-tools-conversation(conversationTitle)
|
||||
<$let currentTiddler=<<conversationTitle>>>
|
||||
|
||||
Server: <$select tiddler=<<currentTiddler>> field="completion-server" default=<<ai-tools-default-llm-completion-server>>>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/AI/CompletionServer]sort[caption]]">
|
||||
<option value=<<currentTiddler>>><$view field='caption'/></option>
|
||||
</$list>
|
||||
</$select>
|
||||
|
||||
<div class="ai-conversation">
|
||||
<$transclude
|
||||
$variable="ai-tools-message"
|
||||
tiddler=<<currentTiddler>>
|
||||
field="system-prompt"
|
||||
role="system"
|
||||
makeLink="no"
|
||||
/>
|
||||
<$list filter="[all[shadows+tiddlers]tag<currentTiddler>!is[draft]sort[created]]" variable="message" storyview="pop">
|
||||
<$transclude
|
||||
$variable="ai-tools-message"
|
||||
tiddler=<<message>>
|
||||
field="text"
|
||||
role={{{ [<message>get[role]] }}}
|
||||
/>
|
||||
</$list>
|
||||
<%if [<ai-tools-status-title>get[text]else[complete]match[pending]] %>
|
||||
<div class="ai-request-status">
|
||||
<div class="ai-request-spinner"></div>
|
||||
</div>
|
||||
<%endif%>
|
||||
<div class="ai-user-prompt">
|
||||
<div class="ai-user-prompt-text">
|
||||
<$edit-text tiddler=<<currentTiddler>> field="current-response-text" tag="textarea" class="tc-edit-texteditor"/>
|
||||
<$button
|
||||
class="ai-user-prompt-send"
|
||||
actions=<<ai-tools-action-get-response>>
|
||||
disabled={{{ [<ai-tools-status-title>get[text]else[complete]match[pending]then[yes]] [<currentTiddler>get[current-response-text]else[]match[]then[yes]] ~[[no]] }}}
|
||||
>
|
||||
Send
|
||||
</$button>
|
||||
</div>
|
||||
<div class="ai-user-prompt-image">
|
||||
<div class="tc-drop-down-wrapper">
|
||||
<$let state=<<qualify "$:/state/ai-user-prompt-image-dropdown-state/">>>
|
||||
<$button popup=<<state>> class="tc-btn-invisible tc-btn-dropdown">Choose an image {{$:/core/images/down-arrow}}</$button>
|
||||
<$link to={{!!current-response-image}}>
|
||||
<$text text={{!!current-response-image}}/>
|
||||
</$link>
|
||||
<$reveal state=<<state>> type="popup" position="belowleft" text="" default="" class="tc-popup-keep">
|
||||
<div class="tc-drop-down" style="text-align:center;">
|
||||
<$transclude
|
||||
$variable="image-picker"
|
||||
filter="[all[shadows+tiddlers]is[image]is[binary]!has[_canonical_uri]] -[type[application/pdf]] +[!has[draft.of]sort[title]]"
|
||||
actions="""
|
||||
<$action-setfield
|
||||
$tiddler=<<currentTiddler>>
|
||||
current-response-image=<<imageTitle>>
|
||||
/>
|
||||
<$action-deletetiddler $tiddler=<<state>>/>
|
||||
"""
|
||||
/>
|
||||
</div>
|
||||
</$reveal>
|
||||
</$let>
|
||||
<$image source={{!!current-response-image}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
\end ai-tools-conversation
|
@ -13,14 +13,14 @@ tags: [[$:/tags/Stylesheet]]
|
||||
box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message {
|
||||
.ai-conversation .ai-tools-message {
|
||||
box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
|
||||
border-radius: 1em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message .ai-message-toolbar {
|
||||
.ai-conversation .ai-tools-message .ai-tools-message-toolbar {
|
||||
background: rgba(1,1,1,0.35);
|
||||
color: white;
|
||||
padding: 0.25em 1em 0.25em 1em;
|
||||
@ -30,11 +30,11 @@ tags: [[$:/tags/Stylesheet]]
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message .ai-message-toolbar .tc-tiddlylink {
|
||||
.ai-conversation .ai-tools-message .ai-tools-message-toolbar .tc-tiddlylink {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message .ai-message-toolbar .ai-message-toolbar-button {
|
||||
.ai-conversation .ai-tools-message .ai-tools-message-toolbar .ai-tools-message-toolbar-button {
|
||||
background: rgba(255,255,255,0.35);
|
||||
color: #333333;
|
||||
cursor: pointer;
|
||||
@ -53,33 +53,33 @@ tags: [[$:/tags/Stylesheet]]
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message .ai-message-toolbar .ai-message-toolbar-button:hover {
|
||||
.ai-conversation .ai-tools-message .ai-tools-message-toolbar .ai-tools-message-toolbar-button:hover {
|
||||
color: #ffffff;
|
||||
background: rgba(255,255,255,0.55);
|
||||
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message .ai-message-body {
|
||||
.ai-conversation .ai-tools-message .ai-tools-message-body {
|
||||
padding: 0 1em 0 1em
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message.ai-message-role-system {
|
||||
.ai-conversation .ai-tools-message.ai-tools-message-role-system {
|
||||
width: 60%;
|
||||
background: #4c4c80;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message.ai-message-role-user {
|
||||
.ai-conversation .ai-tools-message.ai-tools-message-role-user {
|
||||
width: 60%;
|
||||
margin-left: auto;
|
||||
background: #ffcde0;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message.ai-message-role-assistant {
|
||||
.ai-conversation .ai-tools-message.ai-tools-message-role-assistant {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.ai-conversation .ai-message.ai-message-role-error {
|
||||
.ai-conversation .ai-tools-message.ai-tools-message-role-error {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
|
@ -2,168 +2,13 @@ title: $:/plugins/tiddlywiki/ai-tools/view-templates/conversation
|
||||
tags: $:/tags/ViewTemplate
|
||||
list-after: $:/core/ui/ViewTemplate/body
|
||||
|
||||
<!--
|
||||
-->
|
||||
\function statusTitle()
|
||||
[<currentTiddler>addprefix[$:/temp/ai-tools/status/]]
|
||||
\end statusTitle
|
||||
|
||||
<!--
|
||||
Procedure to display a message from an AI conversation. Current tiddler is the conversation tiddler
|
||||
-->
|
||||
\procedure ai-message(tiddler,field,role,makeLink:"yes")
|
||||
<$qualify
|
||||
name="state"
|
||||
title={{{ [[$:/state/ai-message-state/]addsuffix<tiddler>] }}}
|
||||
>
|
||||
<$let
|
||||
editStateTiddler={{{ [<state>addsuffix[-edit-state]] }}}
|
||||
editState={{{ [<editStateTiddler>get[text]else[view]] }}}
|
||||
>
|
||||
<div class={{{ ai-message [<role>addprefix[ai-message-role-]] +[join[ ]] }}}>
|
||||
<div class="ai-message-toolbar">
|
||||
<div class="ai-message-toolbar-left">
|
||||
<$genesis $type={{{ [<makeLink>match[yes]then[$link]else[span]] }}} to=<<tiddler>>>
|
||||
<$text text=<<role>>/>
|
||||
</$genesis>
|
||||
</div>
|
||||
<div class="ai-message-toolbar-left">
|
||||
<%if [<editState>!match[edit]] %>
|
||||
<$button class="ai-message-toolbar-button">
|
||||
<$action-setfield $tiddler=<<editStateTiddler>> text="edit"/>
|
||||
edit
|
||||
</$button>
|
||||
<%endif%>
|
||||
<%if [<editState>!match[view]] %>
|
||||
<$button class="ai-message-toolbar-button">
|
||||
<$action-setfield $tiddler=<<editStateTiddler>> text="view"/>
|
||||
view
|
||||
</$button>
|
||||
<%endif%>
|
||||
<$button class="ai-message-toolbar-button">
|
||||
<$action-sendmessage $message="tm-copy-to-clipboard" $param={{{ [<tiddler>get<field>else[]] }}}/>
|
||||
copy
|
||||
</$button>
|
||||
<$button class="ai-message-toolbar-button">
|
||||
<$action-deletetiddler $tiddler=<<tiddler>>/>
|
||||
delete
|
||||
</$button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ai-message-body">
|
||||
<%if [<editState>match[view]] %>
|
||||
<$transclude $tiddler=<<tiddler>> $field=<<field>> $mode="block"/>
|
||||
<%else%>
|
||||
<$edit-text tiddler=<<tiddler>> field=<<field>> tag="textarea" class="tc-edit-texteditor"/>
|
||||
<%endif%>
|
||||
<%if [<tiddler>get[image]else[]!match[]] %>
|
||||
<$image source={{{ [<tiddler>get[image]] }}}/>
|
||||
<%endif%>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
</$qualify>
|
||||
\end ai-message
|
||||
|
||||
<!--
|
||||
Action procedure to get the next response from the LLM
|
||||
-->
|
||||
\procedure action-get-response()
|
||||
<$let
|
||||
resultTitlePrefix={{{ [<currentTiddler>addsuffix[ - Prompt]] }}}
|
||||
resultTags={{{ [<currentTiddler>format:titlelist[]] }}}
|
||||
>
|
||||
<$action-createtiddler
|
||||
$basetitle=<<resultTitlePrefix>>
|
||||
tags=<<resultTags>>
|
||||
type="text/markdown"
|
||||
role="user"
|
||||
text={{!!current-response-text}}
|
||||
image={{!!current-response-image}}
|
||||
>
|
||||
<$action-deletefield $tiddler=<<currentTiddler>> $field="current-response-text"/>
|
||||
<$action-deletefield $tiddler=<<currentTiddler>> $field="current-response-image"/>
|
||||
<$transclude
|
||||
$variable="get-llm-completion"
|
||||
conversationTitle=<<currentTiddler>>
|
||||
completionServer={{!!completion-server}}
|
||||
resultTitlePrefix=<<resultTitlePrefix>>
|
||||
resultTags=<<resultTags>>
|
||||
statusTitle=<<statusTitle>>
|
||||
/>
|
||||
</$action-createtiddler>
|
||||
</$let>
|
||||
\end action-get-response
|
||||
|
||||
<%if [<currentTiddler>tag[$:/tags/AI/Conversation]] %>
|
||||
|
||||
Server: <$select tiddler=<<currentTiddler>> field="completion-server" default=<<default-llm-completion-server>>>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/AI/CompletionServer]sort[caption]]">
|
||||
<option value=<<currentTiddler>>><$view field='caption'/></option>
|
||||
</$list>
|
||||
</$select>
|
||||
|
||||
<div class="ai-conversation">
|
||||
<$transclude
|
||||
$variable="ai-message"
|
||||
tiddler=<<currentTiddler>>
|
||||
field="system-prompt"
|
||||
role="system"
|
||||
makeLink="no"
|
||||
/>
|
||||
<$list filter="[all[shadows+tiddlers]tag<currentTiddler>!is[draft]sort[created]]" variable="message" storyview="pop">
|
||||
<$transclude
|
||||
$variable="ai-message"
|
||||
tiddler=<<message>>
|
||||
field="text"
|
||||
role={{{ [<message>get[role]] }}}
|
||||
/>
|
||||
</$list>
|
||||
<%if [<statusTitle>get[text]else[complete]match[pending]] %>
|
||||
<div class="ai-request-status">
|
||||
<div class="ai-request-spinner"></div>
|
||||
</div>
|
||||
<%endif%>
|
||||
<div class="ai-user-prompt">
|
||||
<div class="ai-user-prompt-text">
|
||||
<$edit-text tiddler=<<currentTiddler>> field="current-response-text" tag="textarea" class="tc-edit-texteditor"/>
|
||||
<$button
|
||||
class="ai-user-prompt-send"
|
||||
actions=<<action-get-response>>
|
||||
disabled={{{ [<statusTitle>get[text]else[complete]match[pending]then[yes]] [<currentTiddler>get[current-response-text]else[]match[]then[yes]] ~[[no]] }}}
|
||||
>
|
||||
Send
|
||||
</$button>
|
||||
</div>
|
||||
<div class="ai-user-prompt-image">
|
||||
<div class="tc-drop-down-wrapper">
|
||||
<$let state=<<qualify "$:/state/ai-user-prompt-image-dropdown-state/">>>
|
||||
<$button popup=<<state>> class="tc-btn-invisible tc-btn-dropdown">Choose an image {{$:/core/images/down-arrow}}</$button>
|
||||
<$link to={{!!current-response-image}}>
|
||||
<$text text={{!!current-response-image}}/>
|
||||
</$link>
|
||||
<$reveal state=<<state>> type="popup" position="belowleft" text="" default="" class="tc-popup-keep">
|
||||
<div class="tc-drop-down" style="text-align:center;">
|
||||
<$transclude
|
||||
$variable="image-picker"
|
||||
filter="[all[shadows+tiddlers]is[image]is[binary]!has[_canonical_uri]] -[type[application/pdf]] +[!has[draft.of]sort[title]]"
|
||||
actions="""
|
||||
<$action-setfield
|
||||
$tiddler=<<currentTiddler>>
|
||||
current-response-image=<<imageTitle>>
|
||||
/>
|
||||
<$action-deletetiddler $tiddler=<<state>>/>
|
||||
"""
|
||||
/>
|
||||
</div>
|
||||
</$reveal>
|
||||
</$let>
|
||||
<$image source={{!!current-response-image}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<$transclude
|
||||
$variable="ai-tools-conversation"
|
||||
$mode="block"
|
||||
conversationTitle=<<currentTiddler>>
|
||||
/>
|
||||
|
||||
<%endif%>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user