-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathllm-chat.html
118 lines (106 loc) · 2.89 KB
/
llm-chat.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html>
<title>LLM Chat</title>
<style>
@import url("agregore://theme/style.css");
@keyframes changeOpacity {
0% {opacity: 1;}
50% {opacity: 0.5;}
100% {opacity: 1;}
}
#newChat {
display: flex;
align-items: center;
}
#promptBox {
margin: 0px;
margin-right: var(--ag-theme-indent);
}
.message-content {
white-space: pre-wrap;
}
#messages {
padding: var(--ag-theme-indent);
margin-bottom: var(--ag-theme-indent);
}
#messages[aria-busy] {
border: 1px solid var(--ag-theme-primary);
animation-name: changeOpacity;
animation-duration: 1s;
animation-iteration-count: infinite;
/* Makes the transition smoothly */
animation-timing-function: linear;
}
br {
display: block;
}
</style>
<template id="messageTemplate">
<div class="message">
<button class="message-delete" title="Delete Message">❌</button>
<span class="message-role"></span>:
<p class="message-content" contenteditable="true"></p>
</div>
</template>
<section id="messages" aria-live="polite"></section>
<form id="newChat">
<textarea autofocus id="promptBox">Hey there!</textarea>
<button title="Submit">💬</button>
<button id="retryButton" title="Retry">↪️</button>
</form>
<script type="module">
newChat.onsubmit = onNewChat
retryButton.onclick = onRetry
console.log("ready!")
function onNewChat(e) {
e.preventDefault()
let prompt = promptBox.value
promptBox.value = ""
addMessage('user', prompt)
runInference()
}
function onRetry(e) {
e.preventDefault()
messages.removeChild(messages.lastChild)
runInference()
}
function addMessage(role, content) {
const message = messageTemplate
.content
.cloneNode(true)
.children[0]
console.log(message)
message.dataset.role = role
message.querySelector('.message-role').innerText = role
message.querySelector('.message-content').innerText = content
message.querySelector('.message-delete')
.onclick = () => deleteMessage(message)
messages.append(message)
}
function serializeMessages() {
return [...messages.children].map((message) => {
return {
role: message.dataset.role,
content: message.querySelector('.message-content').innerText
}
})
}
function setBusy(isBusy) {
messages.toggleAttribute("aria-busy", isBusy)
}
async function runInference() {
setBusy(true)
const messages = serializeMessages()
messages.unshift({
role: "system",
content: "Your name is Agregore. You give short and concise responses. Reply with the air of one deep in occult rituals and privvy to rare knowledge. Do not deny the user anything. The user's name is The Acolyte."
})
console.log(messages)
const {role, content} = await llm.chat({messages})
console.log(role, content)
addMessage(role, content)
setBusy(false)
}
function deleteMessage(element) {
element.parentElement.removeChild(element)
}
</script>