Mercurial Hosting > lang
changeset 69:f5e72f2d1025
add stt_prompt
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 23 Aug 2025 07:07:59 -0600 |
parents | a366d27db8f1 |
children | 4a73af8f2203 |
files | courses/course.txt src/chat.js src/edit_course.html.luan src/lib/Chat.luan src/lib/Course.luan src/lib/ai/claude/Ai_chat.luan src/new_chat.red.luan src/save_course.js.luan src/stt.js.luan src/view_course.html.luan |
diffstat | 10 files changed, 41 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/courses/course.txt Sat Aug 23 04:32:17 2025 -0600 +++ b/courses/course.txt Sat Aug 23 07:07:59 2025 -0600 @@ -4,6 +4,6 @@ This course is to have Claude help you design your own course. When you make a course and then start a chat, Claude can read that chat if you give Claude the chat ID from the chat URL. This let's you discuss a chat with Claude in a chat of this course. -This is an AI language learning website using the Claude API. Users can create courses on this website by entering a system prompt for Claude. The purpose of this thread/chat is to help users design these courses, mostly by editing the system prompt of the course. This website also has text-to-speech and speech-to-text using OpenAI. A course also has instructions for text-to-speech. +This is an AI language learning website using the Claude API. Users can create courses on this website by entering a system prompt for Claude. The purpose of this thread/chat is to help users design these courses, mostly by editing the system prompt of the course. This website also has text-to-speech and speech-to-text using OpenAI. A course also has instructions for text-to-speech and a prompt for speech-to-text. Users can discuss a chat with you by giving you a chat ID so you can read the chat using the tool/function `get_chat`.
--- a/src/chat.js Sat Aug 23 04:32:17 2025 -0600 +++ b/src/chat.js Sat Aug 23 07:07:59 2025 -0600 @@ -133,6 +133,7 @@ let blob = new Blob(chunks, { type: 'audio/webm' }); let formData = new FormData(); formData.append('audio', blob, 'recording.webm'); + formData.append('prompt', chat.stt_prompt); ajax('stt.js',formData); document.querySelector('button[record]').textContent = 'Record'; };
--- a/src/edit_course.html.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/edit_course.html.luan Sat Aug 23 07:07:59 2025 -0600 @@ -30,6 +30,7 @@ tts_instructions = "" has_ruby = false description = "" + stt_prompt = "" } end Io.stdout = Http.response.text_writer() @@ -83,6 +84,9 @@ <h4>Text to speech instructions</h4> <textarea name=tts_instructions oninput="fixTextarea(event.target)"><%=html_encode(course.tts_instructions)%></textarea> + <h4>Speech to text prompt</h4> + <textarea name=stt_prompt oninput="fixTextarea(event.target)"><%=html_encode(course.stt_prompt)%></textarea> + <input type=submit> <hr>
--- a/src/lib/Chat.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/lib/Chat.luan Sat Aug 23 07:07:59 2025 -0600 @@ -37,6 +37,7 @@ autoplay = doc.autoplay == "true" is_private = doc.is_private == "true" has_ruby = doc.has_ruby == "true" + stt_prompt = doc.stt_prompt or "" } end @@ -50,12 +51,13 @@ name = chat.name or error() ai_thread = chat.ai_thread or error() language = chat.language or error() - tts_instructions = chat.tts_instructions -- or error() + tts_instructions = chat.tts_instructions or error() voice = chat.voice or error() show_text = chat.show_text autoplay = chat.autoplay and "true" or "false" is_private = chat.is_private and "true" or nil has_ruby = chat.has_ruby and "true" or nil + stt_prompt = chat.stt_prompt or error() } end @@ -87,6 +89,7 @@ show_text = chat.show_text autoplay = chat.autoplay is_private = chat.is_private + stt_prompt = chat.stt_prompt } end
--- a/src/lib/Course.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/lib/Course.luan Sat Aug 23 07:07:59 2025 -0600 @@ -27,6 +27,7 @@ tts_instructions = doc.tts_instructions has_ruby = doc.has_ruby == "true" description = doc.description or "" + stt_prompt = doc.stt_prompt or "" } end @@ -43,6 +44,7 @@ tts_instructions = course.tts_instructions or error() has_ruby = course.has_ruby and "true" or nil description = course.description or error() + stt_prompt = course.stt_prompt or error() } end
--- a/src/lib/ai/claude/Ai_chat.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/lib/ai/claude/Ai_chat.luan Sat Aug 23 07:07:59 2025 -0600 @@ -105,7 +105,7 @@ } get_tts_instructions = { tool = { - description = "Get the text-to-speech instructions of a chat/thread on this website. These instruction are passed to OpenAI. If there are no instructions, the empty string is returned." + description = "Get the text-to-speech instructions of a chat/thread on this website. These instructions are passed to OpenAI. If there are no instructions, the empty string is returned." input_schema = { type = "object" properties = { @@ -122,6 +122,25 @@ return chat.tts_instructions or error() end } + get_stt_prompt = { + tool = { + description = "Get the speech-to-text prompt of a chat/thread on this website. This prompt is passed to OpenAI. If there is no prompt, the empty string is returned." + input_schema = { + type = "object" + properties = { + chat_id = { + description = "The ID of the chat" + type = "integer" + } + } + } + } + fn = function(input) + local chat_id = input.chat_id or error() + local chat = get_chat(chat_id) + return chat.stt_prompt or error() + end + } } local tools = {nil} for name, f in pairs(functions) do
--- a/src/new_chat.red.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/new_chat.red.luan Sat Aug 23 07:07:59 2025 -0600 @@ -22,6 +22,7 @@ language = course.language tts_instructions = course.tts_instructions has_ruby = course.has_ruby + stt_prompt = course.stt_prompt ai_thread = ai_init(course.ai_system_prompt) } chat.save()
--- a/src/save_course.js.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/save_course.js.luan Sat Aug 23 07:07:59 2025 -0600 @@ -33,6 +33,7 @@ course.tts_instructions = parameters.tts_instructions or error() course.has_ruby = parameters.has_ruby ~= nil course.description = parameters.description or error() + course.stt_prompt = parameters.stt_prompt or error() course.updated = time_now() course.save() end )
--- a/src/stt.js.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/stt.js.luan Sat Aug 23 07:07:59 2025 -0600 @@ -20,7 +20,7 @@ ["Content-Type"] = "multipart/form-data" } -local function speech_to_text(audio) +local function speech_to_text(audio,prompt) local options = { method = "POST" headers = headers @@ -28,6 +28,7 @@ parameters = { model = "whisper-1" file = audio + prompt = prompt } } local json = uri(url,options).read_text() @@ -38,7 +39,8 @@ return function() local audio = Http.request.parameters.audio or error() - local text = speech_to_text(audio) + local prompt = Http.request.parameters.prompt or error() + local text = speech_to_text(audio,prompt) Io.stdout = Http.response.text_writer() %> setText(<%=json_string(text)%>);
--- a/src/view_course.html.luan Sat Aug 23 04:32:17 2025 -0600 +++ b/src/view_course.html.luan Sat Aug 23 07:07:59 2025 -0600 @@ -70,6 +70,9 @@ <h4>Text to speech instructions</h4> <pre><%=html_encode(course.tts_instructions)%></pre> + <h4>Speech to text prompt</h4> + <pre><%=html_encode(course.stt_prompt)%></pre> + </div> <dialog delete> <h2>Delete Course</h2>