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 |