Mercurial Hosting > lang
annotate src/lib/Chat.luan @ 80:0ae81150d377 default tip
add business plan
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Wed, 03 Sep 2025 15:50:10 -0600 |
| parents | d4473741142c |
| children |
| rev | line source |
|---|---|
| 4 | 1 local Luan = require "luan:Luan.luan" |
| 2 local error = Luan.error | |
| 3 local ipairs = Luan.ipairs or error() | |
| 4 local Number = require "luan:Number.luan" | |
| 5 local long = Number.long or error() | |
| 6 local Time = require "luan:Time.luan" | |
| 7 local time_now = Time.now or error() | |
| 8 local Html = require "luan:Html.luan" | |
| 9 local html_encode = Html.encode or error() | |
| 10 local Db = require "site:/lib/Db.luan" | |
| 5 | 11 local run_in_transaction = Db.run_in_transaction or error() |
| 76 | 12 local Ai_chat = require "site:/lib/claude/Ai_chat.luan" |
| 25 | 13 local Course = require "site:/lib/Course.luan" |
| 14 local get_course_by_id = Course.get_by_id or error() | |
| 31 | 15 local Shared = require "site:/lib/Shared.luan" |
| 16 local voices = Shared.voices or error() | |
| 46 | 17 local languages = Shared.languages or error() |
| 65 | 18 local User = require "site:/lib/User.luan" |
| 19 local get_user_by_id = User.get_by_id or error() | |
| 4 | 20 |
| 21 | |
| 22 local Chat = {} | |
| 23 | |
| 24 local function from_doc(doc) | |
| 25 doc.type == "chat" or error "wrong type" | |
| 26 return Chat.new { | |
| 27 id = doc.id | |
| 28 user_id = doc.chat_user_id | |
| 29 updated = doc.chat_updated | |
| 24 | 30 course_id = doc.course_id |
| 4 | 31 name = doc.name |
| 5 | 32 ai_thread = doc.ai_thread |
| 16 | 33 language = doc.language |
| 46 | 34 tts_instructions = doc.tts_instructions |
| 31 | 35 voice = doc.voice |
| 52 | 36 show_text = doc.show_text |
| 36 | 37 autoplay = doc.autoplay == "true" |
| 41 | 38 is_private = doc.is_private == "true" |
| 52 | 39 has_ruby = doc.has_ruby == "true" |
| 69 | 40 stt_prompt = doc.stt_prompt or "" |
| 4 | 41 } |
| 42 end | |
| 43 | |
| 44 local function to_doc(chat) | |
| 45 return { | |
| 46 type = "chat" | |
| 47 id = chat.id | |
| 48 chat_user_id = long(chat.user_id) | |
| 49 chat_updated = long(chat.updated) | |
| 24 | 50 course_id = long(chat.course_id) |
| 4 | 51 name = chat.name or error() |
|
35
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
52 ai_thread = chat.ai_thread or error() |
| 16 | 53 language = chat.language or error() |
| 69 | 54 tts_instructions = chat.tts_instructions or error() |
| 31 | 55 voice = chat.voice or error() |
| 52 | 56 show_text = chat.show_text |
| 36 | 57 autoplay = chat.autoplay and "true" or "false" |
| 41 | 58 is_private = chat.is_private and "true" or nil |
| 52 | 59 has_ruby = chat.has_ruby and "true" or nil |
| 69 | 60 stt_prompt = chat.stt_prompt or error() |
| 4 | 61 } |
| 62 end | |
| 63 | |
| 64 function Chat.new(chat) | |
| 65 chat.updated = chat.updated or time_now() | |
| 46 | 66 chat.voice = chat.voice or voices[1] |
| 36 | 67 if chat.autoplay==nil then chat.autoplay = true end |
| 4 | 68 |
| 69 function chat.save() | |
| 70 local doc = to_doc(chat) | |
| 71 Db.save(doc) | |
| 72 chat.id = doc.id | |
| 73 end | |
| 74 | |
| 5 | 75 function chat.reload() |
| 76 return Chat.get_by_id(chat.id) or error(chat.id) | |
| 77 end | |
| 78 | |
| 4 | 79 function chat.delete() |
| 80 Db.delete("id:"..chat.id) | |
| 81 end | |
| 82 | |
| 29 | 83 function chat.info() |
| 84 return { | |
| 85 id = chat.id | |
| 31 | 86 voice = chat.voice |
| 46 | 87 tts_instructions = chat.tts_instructions |
| 29 | 88 name = chat.name |
| 34 | 89 show_text = chat.show_text |
| 36 | 90 autoplay = chat.autoplay |
| 41 | 91 is_private = chat.is_private |
| 69 | 92 stt_prompt = chat.stt_prompt |
| 74 | 93 language = chat.language |
| 29 | 94 } |
| 95 end | |
| 96 | |
| 4 | 97 function chat.name_html() |
| 98 return html_encode(chat.name) | |
| 99 end | |
| 100 | |
|
35
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
101 function chat.init_text() -- return text for textarea |
|
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
102 if Ai_chat.has_messages(chat.ai_thread) then |
|
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
103 return "" |
| 25 | 104 end |
| 105 local course = get_course_by_id(chat.course_id) or error() | |
|
35
3117876debca
ai_first_message in textarea
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
106 return course.ai_first_message or error() |
| 25 | 107 end |
| 108 | |
| 109 function chat.output_system_prompt() | |
| 110 Ai_chat.output_system_prompt(chat.ai_thread) | |
| 111 end | |
| 112 | |
| 52 | 113 local function option(name,text) |
| 114 local selected = name==chat.show_text and " selected" or "" | |
| 115 %> | |
| 74 | 116 <option value=<%=name%><%=selected%>><%=text%></option> |
| 52 | 117 <% |
| 118 end | |
| 119 | |
| 120 local function assistant_controls() | |
| 121 return `%> | |
| 122 <div controls> | |
| 123 <audio controls preload=none></audio> | |
| 74 | 124 <select onchange="showSelected(this)"> |
| 52 | 125 <% |
| 74 | 126 option("hide_text","Hide text") |
| 52 | 127 if chat.has_ruby then |
| 128 option("hide_ruby","Hide pronunciation") | |
| 129 end | |
| 74 | 130 option("show_text","Show text") |
| 131 if chat.language ~= "en" then | |
| 132 option("show_trans","Show translation") | |
| 133 end | |
| 52 | 134 %> |
| 135 </select> | |
| 136 </div> | |
| 137 <% ` | |
| 138 end | |
| 139 | |
| 25 | 140 function chat.output_messages_html() |
| 52 | 141 Ai_chat.output_messages_html(assistant_controls(),chat.ai_thread) |
| 25 | 142 end |
| 143 | |
| 71 | 144 function chat.ai_add(input) |
| 25 | 145 local old_thread = chat.ai_thread |
| 71 | 146 local ai_thread = Ai_chat.add(old_thread,input) |
| 147 run_in_transaction( function() | |
| 148 chat = chat.reload() | |
| 149 chat.ai_thread = ai_thread | |
| 150 chat.save() | |
| 151 end ) | |
| 152 return `Ai_chat.output_messages_html(assistant_controls(),ai_thread,old_thread)` | |
| 153 end | |
| 154 | |
| 155 function chat.ai_respond() | |
| 156 local old_thread = chat.ai_thread | |
| 157 local ai_thread = Ai_chat.respond(old_thread) | |
| 25 | 158 run_in_transaction( function() |
| 159 chat = chat.reload() | |
| 160 chat.ai_thread = ai_thread | |
| 161 chat.save() | |
| 162 end ) | |
| 52 | 163 return `Ai_chat.output_messages_html(assistant_controls(),ai_thread,old_thread)` |
| 5 | 164 end |
| 165 | |
| 21 | 166 function chat.language_name() |
| 46 | 167 return languages[chat.language] |
| 21 | 168 end |
| 169 | |
| 65 | 170 function chat.get_user() |
| 171 return get_user_by_id(chat.user_id) | |
| 172 end | |
| 173 | |
| 4 | 174 return chat |
| 175 end | |
| 176 | |
| 177 function Chat.search(query,sort,rows) | |
| 178 rows = rows or 1000000 | |
| 179 local chats = {} | |
| 180 local docs = Db.search(query,1,rows,{sort=sort}) | |
| 181 for _, doc in ipairs(docs) do | |
| 182 chats[#chats+1] = from_doc(doc) | |
| 183 end | |
| 184 return chats | |
| 185 end | |
| 186 | |
| 187 function Chat.get_by_id(id) | |
| 188 local doc = Db.get_document("id:"..id) | |
| 189 return doc and doc.type=="chat" and from_doc(doc) or nil | |
| 190 end | |
| 191 | |
| 192 return Chat |
