1use anyhow::{Context, Result};
2use crate::adapters::input::*;
3use tokio::sync::Mutex;
4use std::{
5 fs::File,
6 io:: BufWriter,
7 sync::Arc,
8 path::PathBuf,
9};
10use tokio;
11use crate::utils::lib::*;
12use clap::Parser;
13use crate::adapters::openai::*;
14use crate::core::assimilator::*;
15use log::debug;
16
17pub async fn run_cli_interface() -> Result<()> {
18 let args = Args::parse();
19 let output_path = get_output_file_path(args.output);
20 let writer = create_writer(&output_path)
21 .context("Failed to create writer")?;
22 let llm = OpenAI::new(args.model, 1.0, 16000);
23 let assimilator = Assimilator::new(llm, writer);
24
25 let prompts = assimilator.tune_prompt(&args.use_case).await
26 .context("Failed to tune prompt")?;
27
28 let chunk_prompt_pairs = prepare_chunk_prompt_pairs(args.input, args.chunk_size, &prompts)
29 .context("Failed to prepare chunk-prompt pairs")?;
30
31 assimilator.harvest(chunk_prompt_pairs).await
32 .context("Failed to harvest chunk-prompt pairs")?;
33
34 assimilator.train(output_path).await
35 .context("Failed to fine-tune LLM")?;
36
37 Ok(())
38}
39
40fn prepare_chunk_prompt_pairs(
41 input_path: PathBuf,
42 chunk_size: usize,
43 prompts: &[String]
44) -> Result<Vec<(String, String)>> {
45 debug!("Preparing chunk-prompt pairs");
46 debug!("Creating FileInputAdapter with input path: {:?} and chunk size: {}", input_path, chunk_size);
47 let input_adapter = FileInputAdapter::new(input_path, chunk_size);
48 let chunks = input_adapter.fetch_chunks()
49 .context("Failed to fetch chunks from input")?;
50 debug!("Creating chunk-prompt pairs");
51 let chunk_prompt_pairs = create_chunk_prompt_pairs(&chunks, prompts);
52 Ok(chunk_prompt_pairs)
53}
54
55fn create_writer(output_path: &PathBuf) -> Result<Arc<Mutex<BufWriter<File>>>> {
56 debug!("Creating writer for output path: {:?}", output_path);
57 let file = File::create(output_path)
58 .context("Failed to create output file")?;
59 let writer: Arc<Mutex<BufWriter<File>>> = Arc::new(Mutex::new(BufWriter::new(file)));
60 Ok(writer)
61}