Skip to content

Commit b80386a

Browse files
committed
fixed tool issues
1 parent cfe339e commit b80386a

File tree

5 files changed

+150
-19
lines changed

5 files changed

+150
-19
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rust_tui_coder"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
edition = "2021"
55
description = "AI-powered terminal coding assistant with interactive TUI, supporting multiple LLMs and comprehensive development tools"
66
license = "MIT OR Apache-2.0"

src/llm.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,32 @@ pub async fn stream_llm_response(
255255
let chunk_str = String::from_utf8_lossy(&bytes);
256256

257257
// SSE format: "data: {...}\n\n"
258-
if let Some(data_line) = chunk_str
259-
.lines()
260-
.find(|line| line.starts_with("data: "))
261-
.and_then(|line| line.strip_prefix("data: "))
262-
{
263-
if data_line == "[DONE]" {
264-
Ok("".to_string()) // End of stream
265-
} else {
266-
// Parse the JSON chunk
267-
match serde_json::from_str::<ChatCompletionStreamResponse>(data_line) {
268-
Ok(parsed) => {
269-
if let Some(choice) = parsed.choices.first() {
270-
Ok(choice.delta.content.clone().unwrap_or_default())
271-
} else {
272-
Ok("".to_string())
258+
// Process ALL data lines in this chunk, not just the first one
259+
let mut collected_content = String::new();
260+
261+
for line in chunk_str.lines() {
262+
if let Some(data_line) = line.strip_prefix("data: ") {
263+
if data_line == "[DONE]" {
264+
continue; // End of stream marker
265+
} else if !data_line.is_empty() {
266+
// Parse the JSON chunk
267+
match serde_json::from_str::<ChatCompletionStreamResponse>(data_line) {
268+
Ok(parsed) => {
269+
if let Some(choice) = parsed.choices.first() {
270+
if let Some(content) = &choice.delta.content {
271+
collected_content.push_str(content);
272+
}
273+
}
274+
}
275+
Err(_) => {
276+
// Skip unparseable chunks silently
273277
}
274278
}
275-
Err(_) => Ok("".to_string()), // Skip unparseable chunks
276279
}
277280
}
278-
} else {
279-
Ok("".to_string())
280281
}
282+
283+
Ok(collected_content)
281284
}
282285
Err(e) => Err(LlmError::RequestFailed(e)),
283286
}

tmp_rovodev_test_prompt.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Test to verify the system prompt looks correct
2+
fn main() {
3+
let system_prompt = r#"You are an AI coding assistant with access to file system tools and development utilities.
4+
5+
## AVAILABLE TOOLS
6+
7+
### Planning and Task Management
8+
1. **CREATE_PLAN** `<task> <steps>` - Create a structured plan in plan.md breaking down tasks into steps
9+
2. **UPDATE_PLAN** `<step_number>` - Mark a specific step as completed in plan.md
10+
3. **CLEAR_PLAN** - Remove plan.md when task is fully completed
11+
12+
### File Operations
13+
4. **READ_FILE** `<path>` - Read and display file contents with line numbers
14+
5. **WRITE_FILE** `<path> <content>` - Create or overwrite files (creates parent directories automatically)"#;
15+
16+
println!("System prompt preview (first 500 chars):");
17+
let preview = if system_prompt.len() > 500 {
18+
&system_prompt[..500]
19+
} else {
20+
system_prompt
21+
};
22+
println!("{}", preview);
23+
println!("\n... (truncated)");
24+
25+
// Count lines
26+
let line_count = system_prompt.lines().count();
27+
println!("\nTotal lines in system prompt: {}", line_count);
28+
println!("Total characters: {}", system_prompt.len());
29+
}

tmp_rovodev_test_wrap

3.75 MB
Binary file not shown.

tmp_rovodev_test_wrap.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Test the wrap_text function
2+
fn wrap_text(text: &str, max_width: usize) -> Vec<String> {
3+
if max_width == 0 {
4+
return vec![text.to_string()];
5+
}
6+
7+
let mut lines = Vec::new();
8+
let mut current_line = String::new();
9+
10+
if text.trim().is_empty() {
11+
return vec![text.to_string()];
12+
}
13+
14+
for line in text.lines() {
15+
if line.trim().is_empty() {
16+
if !current_line.is_empty() {
17+
lines.push(current_line.clone());
18+
current_line.clear();
19+
}
20+
lines.push(String::new());
21+
continue;
22+
}
23+
24+
let words: Vec<&str> = line.split_whitespace().collect();
25+
26+
for word in words {
27+
if word.len() > max_width {
28+
if !current_line.is_empty() {
29+
lines.push(current_line.clone());
30+
current_line.clear();
31+
}
32+
let mut remaining_word = word;
33+
while !remaining_word.is_empty() {
34+
let chunk_size = std::cmp::min(max_width, remaining_word.len());
35+
let chunk = &remaining_word[..chunk_size];
36+
lines.push(chunk.to_string());
37+
remaining_word = &remaining_word[chunk_size..];
38+
}
39+
continue;
40+
}
41+
42+
let space_needed = if current_line.is_empty() {
43+
word.len()
44+
} else {
45+
current_line.len() + 1 + word.len()
46+
};
47+
48+
if space_needed <= max_width {
49+
if !current_line.is_empty() {
50+
current_line.push(' ');
51+
}
52+
current_line.push_str(word);
53+
} else {
54+
if !current_line.is_empty() {
55+
lines.push(current_line.clone());
56+
current_line.clear();
57+
}
58+
current_line.push_str(word);
59+
}
60+
}
61+
62+
if !current_line.is_empty() {
63+
lines.push(current_line.clone());
64+
current_line.clear();
65+
}
66+
}
67+
68+
if !current_line.is_empty() {
69+
lines.push(current_line);
70+
}
71+
72+
if lines.is_empty() {
73+
lines.push(text.to_string());
74+
}
75+
76+
lines
77+
}
78+
79+
fn main() {
80+
let test_text = "Here are the tools:\n1. CREATE_PLAN - Create a plan for complex tasks\n2. UPDATE_PLAN - Mark a step as completed in the plan";
81+
82+
println!("Original text:");
83+
println!("{}", test_text);
84+
println!("\nWrapped at 40 chars:");
85+
let wrapped = wrap_text(test_text, 40);
86+
for (i, line) in wrapped.iter().enumerate() {
87+
println!("{}: '{}'", i, line);
88+
}
89+
90+
// Test garbled-looking text
91+
let garbled = "Here the tools1 CREATE - a plan complex";
92+
println!("\nGarbled text:");
93+
println!("{}", garbled);
94+
println!("\nWrapped at 40 chars:");
95+
let wrapped2 = wrap_text(garbled, 40);
96+
for (i, line) in wrapped2.iter().enumerate() {
97+
println!("{}: '{}'", i, line);
98+
}
99+
}

0 commit comments

Comments
 (0)