Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One Image At a Time -- CAT #521

Merged
merged 6 commits into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/forward_to_openai_endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ pub async fn forward_to_openai_style_endpoint(
}
if model_name != "o1-mini" {
data["temperature"] = serde_json::Value::from(sampling_parameters.temperature);
data["max_tokens"] = serde_json::Value::from(sampling_parameters.max_new_tokens);
data["max_completion_tokens"] = serde_json::Value::from(sampling_parameters.max_new_tokens);
} else {
data["max_completion_tokens"] = serde_json::Value::from(sampling_parameters.max_new_tokens);
Expand Down Expand Up @@ -104,7 +103,6 @@ pub async fn forward_to_openai_style_endpoint_streaming(
"model": model_name,
"stream": true,
"temperature": sampling_parameters.temperature,
"max_tokens": sampling_parameters.max_new_tokens,
"max_completion_tokens": sampling_parameters.max_new_tokens,
"stream_options": {"include_usage": true},
// "stop": sampling_parameters.stop, // openai does not like stop: []
Expand Down
4 changes: 2 additions & 2 deletions src/integrations/integr_cmdline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub fn format_output(stdout_out: &str, stderr_out: &str) -> String {
let mut out = String::new();
if !stdout_out.is_empty() && stderr_out.is_empty() {
// special case: just clean output, nice
out.push_str(&format!("{}\n", stdout_out));
out.push_str(&format!("{}\n\n", stdout_out));
} else {
if !stdout_out.is_empty() {
out.push_str(&format!("STDOUT\n```\n{}```\n\n", stdout_out));
Expand Down Expand Up @@ -195,7 +195,7 @@ pub async fn execute_blocking_command(

let mut out = format_output(&stdout, &stderr);
let exit_code = output.status.code().unwrap_or_default();
out.push_str(&format!("command was running {:.3}s, finished with exit code {exit_code}\n", duration.as_secs_f64()));
out.push_str(&format!("The command was running {:.3}s, finished with exit code {exit_code}\n", duration.as_secs_f64()));
Ok(out)
};

Expand Down
16 changes: 10 additions & 6 deletions src/integrations/integr_shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,24 +212,28 @@ pub async fn execute_shell_command(
}

cmd.arg(shell_arg).arg(command);
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
cmd.stdout(Stdio::piped());
cmd.stderr(Stdio::piped());

let t0 = tokio::time::Instant::now();
tracing::info!("SHELL: running command directory {:?}\n{:?}", workdir_maybe, command);
let output = tokio::time::timeout(tokio::time::Duration::from_secs(timeout), cmd.output())
.await
.map_err(|_| format!("Command timed out after {} seconds", timeout))?
.map_err(|e| format!("Failed to execute command: {}", e))?;
let duration = t0.elapsed();
tracing::info!("SHELL: /finished in {:.3}s", duration.as_secs_f64());

let stdout = String::from_utf8_lossy(&output.stdout).to_string();
let stderr = String::from_utf8_lossy(&output.stderr).to_string();

let filtered_stdout = crate::postprocessing::pp_command_output::output_mini_postprocessing(output_filter, &stdout);
let filtered_stderr = crate::postprocessing::pp_command_output::output_mini_postprocessing(output_filter, &stderr);

if !filtered_stderr.is_empty() {
return Err(filtered_stderr);
}

Ok(filtered_stdout)
let mut out = crate::integrations::integr_cmdline::format_output(&filtered_stdout, &filtered_stderr);
let exit_code = output.status.code().unwrap_or_default();
out.push_str(&format!("The command was running {:.3}s, finished with exit code {exit_code}\n", duration.as_secs_f64()));
Ok(out)
}

fn parse_args(args: &HashMap<String, Value>) -> Result<(String, Option<PathBuf>), String> {
Expand Down
17 changes: 14 additions & 3 deletions src/tools/tool_cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ use image::{ImageFormat, ImageReader};
pub struct ToolCat;


const CAT_MAX_IMAGES_CNT: usize = 1;


#[async_trait]
impl Tool for ToolCat {
fn as_any(&self) -> &dyn std::any::Any { self }

async fn tool_execute(
&mut self,
ccx: Arc<AMutex<AtCommandsContext>>,
Expand Down Expand Up @@ -81,7 +84,7 @@ impl Tool for ToolCat {
}
}
if !not_found_messages.is_empty() {
content.push_str(&format!("Path problems:\n\n{}\n\n", not_found_messages.join("\n\n")));
content.push_str(&format!("Problems:\n{}\n\n", not_found_messages.join("\n\n")));
corrections = true;
}

Expand Down Expand Up @@ -260,14 +263,22 @@ pub async fn paths_and_symbols_to_cat(
.filter_map(|x| if let ContextEnum::ContextFile(cf) = x { Some(cf.file_name.clone()) } else { None })
.collect::<Vec<_>>();

let mut image_counter = 0;
for p in unique_paths.iter().filter(|x|!filenames_got_symbols_for.contains(x)) {
// don't have symbols for these, so we need to mention them as files, without a symbol, analog of @file
let f_type = get_file_type(&PathBuf::from(p));

if f_type.starts_with("image/") {
filenames_present.push(p.clone());
if image_counter == CAT_MAX_IMAGES_CNT {
not_found_messages.push("Cat() shows only 1 image per call to avoid token overflow, call several cat() in parallel to see more images.".to_string());
}
image_counter += 1;
if image_counter > CAT_MAX_IMAGES_CNT {
continue
}
match load_image(p, &f_type).await {
Ok(mm) => {
filenames_present.push(p.clone());
multimodal.push(mm);
},
Err(e) => { not_found_messages.push(format!("{}: {}", p, e)); }
Expand Down