1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
//! # Conversational Translation Bot
//!
//! This example demonstrates a sophisticated translation bot that can:
//! - Automatically detect target language from user input
//! - Translate text to specified language (default: English)
//! - Maintain conversation context for continuous translation
//! - Support streaming responses for real-time feedback
//!
//! ## Usage Examples
//!
//! ```
//! 用户> 你好,翻译成英文
//! AI> Hello
//!
//! 用户> How are you today? 翻译成中文
//! AI> 你今天好吗?
//!
//! 用户> 这是一个测试
//! AI> This is a test
//!
//! 用户> exit
//! ```
//!
//! ## Prerequisites
//!
//! Set the `ZHIPU_API_KEY` environment variable:
//! ```bash
//! export ZHIPU_API_KEY="your-api-key-here"
//! ```
//!
//! ## Running the Example
//!
//! ```bash
//! cargo run --example translation_bot
//! ```
use std::{
io::{self, Write},
sync::Arc,
};
use tokio::sync::Mutex;
use zai_rs::model::*;
/// Language detection result containing target language and confidence
#[derive(Debug, Clone)]
struct LanguageDetection {
target_language: String,
original_text: String,
is_explicit: bool, // Whether user explicitly specified the target language
}
/// Translation bot with conversation state
struct TranslationBot {
model: GLM4_5_flash,
api_key: String,
}
impl TranslationBot {
/// Create a new translation bot instance
fn new(api_key: String) -> Self {
let model = GLM4_5_flash {};
Self { model, api_key }
}
/// Detect target language and extract text to translate from user input
fn detect_language_and_extract_text(&self, input: &str) -> LanguageDetection {
let input_lower = input.to_lowercase();
// Check for explicit language specification
if input_lower.contains("翻译成英文") || input_lower.contains("translate to english") {
if let Some(text) = input.split("翻译成英文").next() {
let text = text.trim();
if !text.is_empty() {
return LanguageDetection {
target_language: "English".to_string(),
original_text: text.to_string(),
is_explicit: true,
};
}
}
if let Some(text) = input.split("translate to english").next() {
let text = text.trim();
if !text.is_empty() {
return LanguageDetection {
target_language: "English".to_string(),
original_text: text.to_string(),
is_explicit: true,
};
}
}
}
if input_lower.contains("翻译成中文") || input_lower.contains("translate to chinese") {
if let Some(text) = input.split("翻译成中文").next() {
let text = text.trim();
if !text.is_empty() {
return LanguageDetection {
target_language: "Chinese".to_string(),
original_text: text.to_string(),
is_explicit: true,
};
}
}
if let Some(text) = input.split("translate to chinese").next() {
let text = text.trim();
if !text.is_empty() {
return LanguageDetection {
target_language: "Chinese".to_string(),
original_text: text.to_string(),
is_explicit: true,
};
}
}
}
// Try to detect if input is non-English text that needs translation to English
if self.contains_non_latin_characters(input) && !input_lower.contains("translate") {
return LanguageDetection {
target_language: "English".to_string(),
original_text: input.trim().to_string(),
is_explicit: false,
};
}
// Default: translate to English
LanguageDetection {
target_language: "English".to_string(),
original_text: input.trim().to_string(),
is_explicit: false,
}
}
/// Simple check for non-Latin characters (basic language detection)
fn contains_non_latin_characters(&self, text: &str) -> bool {
text.chars().any(|c| !c.is_ascii() && c.is_alphabetic())
}
/// Create translation prompt based on detection
fn create_translation_prompt(&self, detection: &LanguageDetection) -> String {
format!(
"请将以下文本翻译成{}:\n\n{}",
detection.target_language, detection.original_text
)
}
/// Translate text with streaming support
async fn translate_stream(&mut self, text: &str) -> Result<String, Box<dyn std::error::Error>> {
let detection = self.detect_language_and_extract_text(text);
let prompt = self.create_translation_prompt(&detection);
println!(
"🎯 目标语言: {} ({})",
detection.target_language,
if detection.is_explicit {
"用户指定"
} else {
"自动检测"
}
);
print!("🔄 翻译中: ");
io::stdout().flush().ok();
// Create client with system message and user prompt
let system_message = TextMessage::system(
"你是一个专业的翻译助手。请将用户提供的文本翻译成指定的语言。\
如果用户没有指定目标语言,默认翻译成英文。\
请只返回翻译结果,不要添加额外的解释或说明。",
);
let client = ChatCompletion::new(self.model.clone(), system_message, self.api_key.clone())
.add_messages(TextMessage::user(&prompt))
.with_temperature(0.3)
.with_top_p(0.9)
.with_thinking(ThinkingType::disabled());
let result = Arc::new(Mutex::new(String::new()));
let result_clone = result.clone();
// Enable streaming for real-time feedback
let mut streaming_client = client.enable_stream();
let finish = Arc::new(Mutex::new(None::<String>));
let finish_clone = finish.clone();
streaming_client
.stream_for_each(move |chunk: ChatStreamResponse| {
let result = result_clone.clone();
let finish = finish_clone.clone();
async move {
if let Some(content) = chunk
.choices
.first()
.and_then(|c| c.delta.as_ref())
.and_then(|d| d.content.as_deref())
{
print!("{}", content);
let _ = std::io::stdout().flush();
// Store the result
let mut result_guard = result.lock().await;
result_guard.push_str(content);
}
if let Some(reason) =
chunk.choices.first().and_then(|c| c.finish_reason.as_ref())
{
let mut finish_guard = finish.lock().await;
*finish_guard = Some(reason.clone());
}
Ok(())
}
})
.await?;
println!(); // New line after streaming
let translation_result = result.lock().await.clone();
Ok(translation_result)
}
/// Start the interactive translation loop
async fn run(&mut self) -> Result<(), Box<dyn std::error::Error>> {
println!("🤖 智能翻译机器人已启动!");
println!("💡 使用方法:");
println!(" - 直接输入文本进行翻译(默认翻译为英文)");
println!(" - 使用 '翻译成[语言]' 或 'translate to [language]' 指定目标语言");
println!(" - 输入 'exit' 或 'quit' 退出程序");
println!(" - 输入 'help' 查看帮助");
println!();
let mut input = String::new();
loop {
print!("📝 请输入要翻译的文本> ");
io::stdout().flush().ok();
input.clear();
io::stdin().read_line(&mut input)?;
let user_input = input.trim().to_string();
if user_input.is_empty() {
continue;
}
match user_input.to_lowercase().as_str() {
"exit" | "quit" | "退出" => {
println!("👋 再见!");
break;
},
"help" | "帮助" => {
self.show_help();
continue;
},
_ => {
// Perform translation
match self.translate_stream(&user_input).await {
Ok(_) => {
println!(); // Add spacing
},
Err(e) => {
eprintln!("❌ 翻译出错: {}", e);
println!();
},
}
},
}
}
Ok(())
}
/// Display help information
fn show_help(&self) {
println!("📖 帮助信息:");
println!();
println!("🔧 支持的命令:");
println!(" • 直接输入文本:自动翻译(默认为英文)");
println!(" • '翻译成英文' / 'translate to English':指定目标语言");
println!(" • 'help' / '帮助':显示此帮助信息");
println!(" • 'exit' / 'quit' / '退出':退出程序");
println!();
println!("🌍 支持的语言:");
println!(" • 中文、英文、日文、韩文、法文、德文、西班牙文");
println!();
println!("💡 示例:");
println!(" • '你好,翻译成英文' → 'Hello'");
println!(" • 'How are you? 翻译成中文' → '你好吗?'");
println!(" • 'Bonjour' → 'Hello'(自动检测为非英文)");
println!();
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
env_logger::init();
// Get API key from environment variable
let api_key = std::env::var("ZHIPU_API_KEY").expect("请设置环境变量 ZHIPU_API_KEY");
// Create and run the translation bot
let mut bot = TranslationBot::new(api_key);
bot.run().await?;
Ok(())
}