Mercurial Hosting > lang
comparison src/lib/ai/claude/Ai_chat.luan @ 19:0351b3d474f8
minor
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Wed, 30 Jul 2025 15:28:09 -0600 |
| parents | src/lib/ai/claude/Chat.luan@f5425a3c1898 |
| children | 27989d63fc71 |
comparison
equal
deleted
inserted
replaced
| 18:820136c5ee33 | 19:0351b3d474f8 |
|---|---|
| 1 local Luan = require "luan:Luan.luan" | |
| 2 local error = Luan.error | |
| 3 local ipairs = Luan.ipairs or error() | |
| 4 local type = Luan.type or error() | |
| 5 local String = require "luan:String.luan" | |
| 6 local starts_with = String.starts_with or error() | |
| 7 local Html = require "luan:Html.luan" | |
| 8 local html_encode = Html.encode or error() | |
| 9 local Parsers = require "luan:Parsers.luan" | |
| 10 local json_parse = Parsers.json_parse or error() | |
| 11 local json_string = Parsers.json_string or error() | |
| 12 local Claude = require "site:/lib/ai/claude/Claude.luan" | |
| 13 local claude_chat = Claude.chat or error() | |
| 14 local Logging = require "luan:logging/Logging.luan" | |
| 15 local logger = Logging.logger "claude/Ai_chat" | |
| 16 | |
| 17 | |
| 18 local Ai_chat = {} | |
| 19 | |
| 20 function Ai_chat.output_system_prompt(thread) | |
| 21 if thread == nil then | |
| 22 return | |
| 23 end | |
| 24 thread = json_parse(thread) | |
| 25 local system_prompt = thread.system or error | |
| 26 system_prompt = html_encode(system_prompt) | |
| 27 %><%=system_prompt%><% | |
| 28 end | |
| 29 | |
| 30 function Ai_chat.output_messages_html(lang,thread,old_thread) | |
| 31 if thread == nil then | |
| 32 return | |
| 33 end | |
| 34 thread = json_parse(thread) | |
| 35 local messages = thread.messages or error | |
| 36 local n = 0 | |
| 37 if old_thread ~= nil then | |
| 38 old_thread = json_parse(old_thread) | |
| 39 local old_messages = old_thread.messages or error | |
| 40 n = #old_messages | |
| 41 end | |
| 42 for i, message in ipairs(messages) do | |
| 43 if i <= n then | |
| 44 continue | |
| 45 end | |
| 46 local role = message.role or error() | |
| 47 local who | |
| 48 if role=="assistant" then | |
| 49 who = "Claude" | |
| 50 elseif role=="user" then | |
| 51 who = "You" | |
| 52 else | |
| 53 error(role) | |
| 54 end | |
| 55 local function output(text) | |
| 56 text = html_encode(text) | |
| 57 %> | |
| 58 <h3><%=who%></h3> | |
| 59 <div markdown role="<%=role%>" lang="<%=lang%>"><%=text%></div> | |
| 60 <% | |
| 61 end | |
| 62 local content = message.content or error() | |
| 63 if type(content) == "string" then | |
| 64 output(content) | |
| 65 else | |
| 66 for _, part in ipairs(content) do | |
| 67 if part.type=="text" then | |
| 68 local text = part.text or error() | |
| 69 output(text) | |
| 70 end | |
| 71 end | |
| 72 end | |
| 73 end_for | |
| 74 end | |
| 75 | |
| 76 | |
| 77 local system_prompt = [[ | |
| 78 CRITICAL REQUIREMENT: When writing Japanese, use ruby markdown syntax {japanese|romaji} for pronunciation guidance. | |
| 79 | |
| 80 Apply ruby tags to meaningful pronunciation units: | |
| 81 - Individual kanji or kanji compounds: {私|watashi}, {学生|gakusei} | |
| 82 - Hiragana/katakana words and particles: {は|wa}, {です|desu}, {ありがとう|arigatō} | |
| 83 - Grammatical elements: {ました|mashita}, {ません|masen} | |
| 84 | |
| 85 The romaji must reflect ACTUAL PRONUNCIATION, not character-by-character readings. | |
| 86 Use macrons for long vowels: ā, ī, ū, ē, ō | |
| 87 | |
| 88 APPLIES TO ALL JAPANESE TEXT: Example sentences, grammar explanations, vocabulary lists, casual mentions - ANY Japanese characters in your response need ruby tags. | |
| 89 | |
| 90 VERIFICATION STEP: Before sending, scan your ENTIRE response for any Japanese characters (hiragana, katakana, kanji) and ensure they all have ruby tags. | |
| 91 ]] | |
| 92 | |
| 93 | |
| 94 function Ai_chat.ask(thread,input) | |
| 95 thread = thread and json_parse(thread) or { | |
| 96 system = system_prompt | |
| 97 messages = {nil} | |
| 98 } | |
| 99 local messages = thread.messages or error | |
| 100 messages[#messages+1] = { | |
| 101 role = "user" | |
| 102 content = input | |
| 103 } | |
| 104 --[=[ | |
| 105 messages[#messages+1] = { | |
| 106 role = "assistant" | |
| 107 content = [[ | |
| 108 hello | |
| 109 ]] | |
| 110 } | |
| 111 if true then | |
| 112 return json_string(thread) | |
| 113 end | |
| 114 --]=] | |
| 115 local resultJson = claude_chat(thread) | |
| 116 local result = json_parse(resultJson) | |
| 117 -- logger.info(json_string(result)) | |
| 118 result.type == "message" or error() | |
| 119 result.role == "assistant" or error() | |
| 120 result.stop_reason == "end_turn" or result.stop_reason == "tool_use" or error() | |
| 121 local content = result.content or error() | |
| 122 messages[#messages+1] = { | |
| 123 role = "assistant" | |
| 124 content = content | |
| 125 } | |
| 126 return json_string(thread) | |
| 127 end | |
| 128 | |
| 129 return Ai_chat |
