changeset 5:a970b7a01a74

start ai
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 16 Jul 2025 15:08:14 -0600
parents b1adec083e44
children 025bb19b65b1
files src/ai_ask.js.luan src/chat.html.luan src/chat.js src/lib/Chat.luan src/lib/ai/Ai.luan src/lib/ai/chatgpt/Chat.luan
diffstat 6 files changed, 101 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai_ask.js.luan	Wed Jul 16 15:08:14 2025 -0600
@@ -0,0 +1,30 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local Parsers = require "luan:Parsers.luan"
+local json_string = Parsers.json_string or error()
+local Io = require "luan:Io.luan"
+local Http = require "luan:http/Http.luan"
+local User = require "site:/lib/User.luan"
+local current_user = User.current or error()
+local Chat = require "site:/lib/Chat.luan"
+local get_chat_by_id = Chat.get_by_id or error()
+
+
+return function()
+	Io.stdout = Http.response.text_writer()
+	local parameters = Http.request.parameters
+	local chat = parameters.chat or error()
+	chat = get_chat_by_id(chat) or error()
+	chat.user_id == current_user().id or error()
+	local input = parameters.input or error()
+	if input == "" then
+%>
+		hideWaitingAiIcon();
+<%
+		return
+	end
+	local html = chat.ask(input)
+%>
+	updateAi(<%=json_string(html)%>);
+<%
+end
--- a/src/chat.html.luan	Tue Jul 08 22:15:41 2025 -0600
+++ b/src/chat.html.luan	Wed Jul 16 15:08:14 2025 -0600
@@ -58,6 +58,7 @@
 			</div>
 			<div scroll>
 				<div messages>
+<%					chat.output_messages_html() %>
 				</div>
 			</div>
 			<div ask>
--- a/src/chat.js	Tue Jul 08 22:15:41 2025 -0600
+++ b/src/chat.js	Wed Jul 16 15:08:14 2025 -0600
@@ -31,6 +31,23 @@
 	document.querySelector('[waiting-ai-icon]').style.display = 'block';
 }
 
+function hideWaitingAiIcon() {
+	document.querySelector('[waiting-ai-icon]').style.display = 'none';
+}
+
+function updateAi(html) {
+	hideWaitingAiIcon();
+	document.querySelector('div[messages]').innerHTML = html;
+	//handleMarkdown();
+	document.querySelector('textarea').focus();
+/*
+	let scroll = aiDialog.querySelector('[scroll]');
+	setTimeout(function(){
+		scroll.scrollTo(0,scroll.scrollHeight);
+	});
+*/
+}
+
 const isMobile = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
 
 function textareaKey(event) {
@@ -49,7 +66,7 @@
 
 function askAi() {
 	let input = document.querySelector('textarea');
-	let url = `ai_ask.js?key=${chatId}&input=${encodeURIComponent(input.value)}`;
+	let url = `ai_ask.js?chat=${chatId}&input=${encodeURIComponent(input.value)}`;
 	ajax(url);
 	input.value = '';
 	showWaitingAiIcon();
--- a/src/lib/Chat.luan	Tue Jul 08 22:15:41 2025 -0600
+++ b/src/lib/Chat.luan	Wed Jul 16 15:08:14 2025 -0600
@@ -8,6 +8,8 @@
 local Html = require "luan:Html.luan"
 local html_encode = Html.encode or error()
 local Db = require "site:/lib/Db.luan"
+local run_in_transaction = Db.run_in_transaction or error()
+local Ai = require "site:/lib/ai/Ai.luan"
 
 
 local Chat = {}
@@ -19,7 +21,8 @@
 		user_id = doc.chat_user_id
 		updated = doc.chat_updated
 		name = doc.name
-		ai_key = doc.ai_key
+		ai_name = doc.ai_name
+		ai_thread = doc.ai_thread
 	}
 end
 
@@ -30,12 +33,15 @@
 		chat_user_id = long(chat.user_id)
 		chat_updated = long(chat.updated)
 		name = chat.name or error()
-		ai_key = chat.ai_key -- or error()
+		ai_name = chat.ai_name or error()
+		ai_thread = chat.ai_thread -- or error()
 	}
 end
 
 function Chat.new(chat)
 	chat.updated = chat.updated or time_now()
+	chat.ai_name = chat.ai_name or "chatgpt"
+	chat.ai = Ai[chat.ai_name]["Chat.luan"] or error()
 
 	function chat.save()
 		local doc = to_doc(chat)
@@ -43,6 +49,10 @@
 		chat.id = doc.id
 	end
 
+	function chat.reload()
+		return Chat.get_by_id(chat.id) or error(chat.id)
+	end
+
 	function chat.delete()
 		Db.delete("id:"..chat.id)
 	end
@@ -51,6 +61,22 @@
 		return html_encode(chat.name)
 	end
 
+	function chat.output_messages_html()
+		chat.ai.output_messages_html(chat.ai_thread)
+	end
+
+	function chat.ask(input)
+		local ai_thread = chat.ai.ask(chat.ai_thread,input)
+		if chat.ai_thread ~= ai_thread then
+			run_in_transaction( function()
+				chat = chat.reload()
+				chat.ai_thread = ai_thread
+				chat.save()
+			end )
+		end
+		return `chat.ai.output_messages_html(ai_thread)`
+	end
+
 	return chat
 end
 
--- a/src/lib/ai/Ai.luan	Tue Jul 08 22:15:41 2025 -0600
+++ b/src/lib/ai/Ai.luan	Wed Jul 16 15:08:14 2025 -0600
@@ -1,13 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
+local ipairs = Luan.ipairs or error()
 
 
 local Ai = {}
 
-local ai = "dummy"
-
-function Ai.require_ai(file)
-	return require("site:/private/lib/ai/"..ai.."/"..file)
+local ais = {"chatgpt"}
+local files = {"Chat.luan"}
+for _, ai in ipairs(ais) do
+	local mods = {}
+	local dir = "site:/lib/ai/"..ai.."/"
+	for _, file in ipairs(files) do
+		mods[file] = require(dir..file)
+	end
+	Ai[ai] = mods
 end
 
 return Ai
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/ai/chatgpt/Chat.luan	Wed Jul 16 15:08:14 2025 -0600
@@ -0,0 +1,14 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+
+
+local Chat = {}
+
+function Chat.output_messages_html(thread)
+end
+
+function Chat.ask(thread,input)
+	return nil
+end
+
+return Chat