Skip to content

Commit d1f3bcf

Browse files
committed
feat(clex_llm): expose default codegen language type
feat(cpast): --problem_url args in ai and test routes feat(cscrapper): new ProgramStore api new_from_language chore(cpast_api): updated schema to store language name in cache and use language from clex_llm instead of c++ as default
1 parent a7be429 commit d1f3bcf

24 files changed

+316
-90
lines changed

.sqlx/query-63bdeb19e8cace053771d10515dd93eb7f583e7612cabd52d634335606a8cfde.json

Lines changed: 0 additions & 22 deletions
This file was deleted.

.sqlx/query-379c67534427b83f2db00aa7a3b7d0d0ddd349a3d426d3c471e7be8bd26d8a21.json renamed to .sqlx/query-c4fad0683162d8a33694a72082fddafda347ba88a493421f0130d2c765c42a6c.json

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-cf3e1d7044a8765a858edb41da4208a269d7a3cfa606783c5eed6579e3ebe589.json

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ccode_runner/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ rust-version.workspace = true
1919
which = { workspace = true }
2020
serde = { features = ["derive"], workspace = true }
2121
utoipa = { workspace = true }
22-
tokio.workspace = true
22+
tokio = { workspace = true }
2323
tempfile = { workspace = true }
2424
rand = { workspace = true }
2525
regex = { workspace = true }

ccode_runner/src/lang_runner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
pub(crate) mod file_store;
1212
pub mod language_name;
1313
pub mod program_store;
14-
pub(crate) mod runner;
14+
pub mod runner;
1515
pub mod runner_error_types;

ccode_runner/src/lang_runner/program_store.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ impl ProgramStore {
6868
})
6969
}
7070

71+
pub fn new_from_language(
72+
correct_lang: Language,
73+
test_lang: Language,
74+
) -> Result<Self, Box<RunnerErrorType>> {
75+
Ok(ProgramStore {
76+
correct_file: correct_lang,
77+
test_file: test_lang,
78+
})
79+
}
80+
7181
/// Run both correct and test files with the given input and compare their outputs
7282
///
7383
/// # Arguments

ccode_runner/src/lang_runner/runner.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,14 @@ use super::language_name::{CompilationType, LanguageName};
77
use super::runner_error_types::RunnerErrorType;
88

99
#[derive(Debug)]
10-
pub(crate) struct Language {
10+
pub struct Language {
1111
pub(crate) code: SourceCodeInfo,
1212
is_compiled: bool, // For program optimization
1313
do_force_compile: bool,
1414
}
1515

1616
impl Language {
17-
pub(crate) fn new(
18-
file_path: &Path,
19-
do_force_compile: bool,
20-
) -> Result<Self, Box<RunnerErrorType>> {
17+
pub fn new(file_path: &Path, do_force_compile: bool) -> Result<Self, Box<RunnerErrorType>> {
2118
let code = SourceCodeInfo::new(file_path)?;
2219

2320
let mut lang = Self {
@@ -34,7 +31,7 @@ impl Language {
3431
Ok(lang)
3532
}
3633

37-
pub(crate) fn new_from_custom_dest(
34+
pub fn new_from_custom_dest(
3835
file_path: &Path,
3936
dest_path: Option<&Path>,
4037
do_force_compile: bool,
@@ -55,7 +52,7 @@ impl Language {
5552
Ok(lang)
5653
}
5754

58-
pub(crate) fn new_from_text(
55+
pub fn new_from_text(
5956
source_text: &str,
6057
lang: LanguageName,
6158
do_force_compile: bool,

clex_llm/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@ rust-version.workspace = true
1515
serde = { workspace = true, features = ["derive"] }
1616
google-generative-ai-rs = { workspace = true, features = ["beta"] }
1717
tokio = { workspace = true, features = ["full"] }
18-
19-
[dev-dependencies]
2018
ccode_runner = { path = "../ccode_runner", version = "0.3.2"}

clex_llm/src/code_generator/runner.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ccode_runner::lang_runner::language_name::LanguageName;
12
use google_generative_ai_rs::v1::{
23
api::{Client, PostResult},
34
errors::GoogleAPIError,
@@ -12,6 +13,7 @@ use super::examples::{self, SolutionTurn};
1213
pub struct CodeSolutionGenerator {
1314
examples: Vec<SolutionTurn>,
1415
client: Client,
16+
language: LanguageName,
1517
}
1618

1719
impl CodeSolutionGenerator {
@@ -20,7 +22,15 @@ impl CodeSolutionGenerator {
2022

2123
let client = Client::new_from_model(Model::Gemini2_0Flash, api_key.to_string());
2224

23-
Ok(CodeSolutionGenerator { examples, client })
25+
Ok(CodeSolutionGenerator {
26+
examples,
27+
client,
28+
language: LanguageName::Cpp,
29+
})
30+
}
31+
32+
pub(crate) fn get_language(&self) -> &LanguageName {
33+
&self.language
2434
}
2535

2636
fn get_system_prompt(&self) -> &str {

clex_llm/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
//!
3232
//! # Prerequisites
3333
//! - A valid Google Generative AI API key (get the API key from <https://makersuite.google.com/app/apikey>)
34+
use ccode_runner::lang_runner::language_name::LanguageName;
3435
use clex_generator::runner::ClexPromptGenerator;
3536
use code_generator::runner::CodeSolutionGenerator;
3637
use google_generative_ai_rs::v1::errors::GoogleAPIError;
@@ -100,8 +101,11 @@ pub async fn generate_code_solution(
100101
statement: &str,
101102
input_format: &str,
102103
constraints: &str,
103-
) -> Result<String, GoogleAPIError> {
104-
generator
105-
.generate_response(statement, input_format, constraints)
106-
.await
104+
) -> Result<(String, LanguageName), GoogleAPIError> {
105+
Ok((
106+
generator
107+
.generate_response(statement, input_format, constraints)
108+
.await?,
109+
generator.get_language().clone(),
110+
))
107111
}

clex_llm/tests/test_code_generator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ async fn test_generate_code_solution() {
2020
let result = generate_code_solution(&generator, statement, input_format, constraints).await;
2121

2222
match result {
23-
Ok(solution) => {
23+
Ok((solution, language_name)) => {
2424
let correct_code = r#"n = int(input())
2525
arr = list(map(int, input().split()))
2626
print(sum(arr))"#;
2727
let runner = ProgramStore::new_from_text(
2828
correct_code,
2929
&solution,
30-
LanguageName::Python,
30+
language_name,
3131
LanguageName::Python,
3232
false,
3333
)

cpast/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ clap_complete = { workspace = true }
2323
clex_gen = { version = "^0.3.2", path = "../clex_gen" }
2424
ccode_runner = { version = "^0.3.2", path = "../ccode_runner" }
2525
clex_llm = { version = "^0.2.2", path = "../clex_llm" }
26+
cscrapper = { path = "../cscrapper" }
2627
thiserror = { workspace = true }
2728

2829
[dev-dependencies]

cpast/examples/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use std::env;
22

3-
use cpast::compile_and_test;
3+
use cpast::{CodeOrPath, compile_and_test};
44

55
#[tokio::main(flavor = "multi_thread", worker_threads = 64)]
66
async fn main() {
77
let manifest_dir = env!("CARGO_MANIFEST_DIR");
88

99
compile_and_test(
1010
format!("{manifest_dir}/examples/res/correct_approach.cpp"),
11-
format!("{manifest_dir}/examples/res/my_approach.cpp"),
11+
CodeOrPath::Path(format!("{manifest_dir}/examples/res/my_approach.cpp")),
1212
"(N[1,5]) (?:(N[1,5]) (?:N[1,100]){\\2}){\\1}".to_owned(),
1313
100,
1414
true,

cpast/examples/test_multilang.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use std::env;
22

3-
use cpast::compile_and_test;
3+
use cpast::{CodeOrPath, compile_and_test};
44

55
#[tokio::main(flavor = "multi_thread", worker_threads = 64)]
66
async fn main() {
77
let manifest_dir = env!("CARGO_MANIFEST_DIR");
88

99
compile_and_test(
1010
format!("{manifest_dir}/examples/res/hello.py"),
11-
format!("{manifest_dir}/examples/res/hello.java"),
11+
CodeOrPath::Path(format!("{manifest_dir}/examples/res/hello.java")),
1212
"N".to_owned(),
1313
100,
1414
true,

cpast/src/cli/cli_parser.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ pub(crate) struct TestArgs {
4747
pub(crate) correct_file: Option<String>,
4848

4949
/// The test file
50-
#[arg(short, long, required = true, value_hint = ValueHint::FilePath)]
50+
#[arg(short, long, value_hint = ValueHint::FilePath)]
5151
pub(crate) test_file: Option<String>,
5252

5353
/// Clex for generating Tests
54-
#[arg(short, long, required = true, value_hint = ValueHint::Other)]
54+
#[arg(short, long, value_hint = ValueHint::Other)]
5555
pub(crate) generator: Option<String>,
5656

57+
/// Coding Problem URL
58+
#[arg(short='u', long, value_hint = ValueHint::Url)]
59+
pub(crate) problem_url: Option<String>,
60+
5761
/// Max number of times of iterations
5862
#[arg(short, long, default_value_t = DEFAULT_ITERATIONS_COUNT, value_hint = ValueHint::Other)]
5963
pub(crate) iterations: usize,
@@ -84,13 +88,17 @@ pub(crate) struct GenerateArgs {
8488
#[derive(clap::Args)]
8589
pub(crate) struct AiArgs {
8690
/// Input format
87-
#[arg(short, long, required = true, value_hint = ValueHint::Other)]
91+
#[arg(short, long, value_hint = ValueHint::Other)]
8892
pub(crate) input_format: Option<String>,
8993

9094
/// Constraints
91-
#[arg(short, long, required = true, value_hint = ValueHint::Other)]
95+
#[arg(short, long, value_hint = ValueHint::Other)]
9296
pub(crate) constraints: Option<String>,
9397

98+
/// Problem URL
99+
#[arg(short='u', long, value_hint = ValueHint::Url)]
100+
pub(crate) problem_url: Option<String>,
101+
94102
/// Copy clex to clipboard
95103
#[arg(long)]
96104
pub(crate) clipboard: bool,

cpast/src/cmd/ai.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,55 @@
55
use cli_clipboard::{ClipboardContext, ClipboardProvider};
66

77
use colored::Colorize;
8+
use cscrapper::qscrapper::ScraperError;
89

910
use crate::{cli::cli_parser::AiArgs, error_types::cli_error::CliErrorType};
1011

1112
pub(crate) async fn generate_clex_from_input_format_and_constraints(
1213
args: AiArgs,
1314
) -> Result<(), Box<CliErrorType>> {
15+
if !((args.problem_url.is_some() && args.input_format.is_none() && args.constraints.is_none())
16+
|| (args.problem_url.is_none()
17+
&& args.input_format.is_some()
18+
&& args.constraints.is_some()))
19+
{
20+
return Err(Box::new(CliErrorType::AiRequiredArgsMissing));
21+
}
22+
1423
let api_key = std::env::var("GOOGLE_API_KEY").ok();
1524

1625
match api_key {
1726
Some(api_key) => {
1827
let generator = clex_llm::create_clex_generator(&api_key)
1928
.map_err(|err| Box::new(CliErrorType::ClexLLMInitilizationError(err)))?;
2029

21-
let input_format = match args.input_format {
22-
Some(input_format) => input_format,
23-
None => {
24-
return Err(Box::new(CliErrorType::InputFormatMissing));
25-
}
26-
};
30+
let (input_format, constraints) = match args.problem_url {
31+
Some(problem_url) => {
32+
let parsed_url = cscrapper::parse_problem_url(&problem_url).ok_or(Box::new(
33+
CliErrorType::CScrapperError(ScraperError::ProblemNotFound),
34+
))?;
35+
let response = cscrapper::get_problem_statement(parsed_url)
36+
.await
37+
.map_err(|err| Box::new(CliErrorType::CScrapperError(err)))?;
2738

28-
let constraints = match args.constraints {
29-
Some(constraints) => constraints,
39+
(response.input_format, response.constraints)
40+
}
3041
None => {
31-
return Err(Box::new(CliErrorType::ConstraintsMissing));
42+
let input_format = match args.input_format {
43+
Some(input_format) => input_format,
44+
None => {
45+
return Err(Box::new(CliErrorType::InputFormatMissing));
46+
}
47+
};
48+
49+
let constraints = match args.constraints {
50+
Some(constraints) => constraints,
51+
None => {
52+
return Err(Box::new(CliErrorType::ConstraintsMissing));
53+
}
54+
};
55+
56+
(input_format, constraints)
3257
}
3358
};
3459

0 commit comments

Comments
 (0)