Skip to content

Commit 479fdf7

Browse files
welkeyeverAsterDY
authored andcommitted
feat: support function cascade compress according to id (cloudwego#21)
* feat: support function cascade compress according to id * feat: add debug logs * feat: add compress for method * feat: add compress all for functions/methods
1 parent b8a1ff0 commit 479fdf7

1 file changed

Lines changed: 91 additions & 34 deletions

File tree

src/compress/compress.rs

Lines changed: 91 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ pub struct Repository {
1313
#[serde(rename = "ModName")]
1414
mod_name: String,
1515
#[serde(rename = "Packages")]
16-
packages: HashMap<String, Package>,
16+
pub packages: HashMap<String, Package>,
1717
}
1818

1919
#[derive(Serialize, Deserialize, Debug)]
2020
pub struct Package {
2121
#[serde(rename = "Functions")]
22-
functions: HashMap<String, Function>,
22+
pub functions: HashMap<String, Function>,
2323
#[serde(rename = "Types")]
2424
types: HashMap<String, Struct>,
2525
}
@@ -44,6 +44,9 @@ pub struct Function {
4444
internal_method_calls: Option<HashMap<String, Identity>>,
4545
#[serde(rename = "ThirdPartyMethodCalls")]
4646
third_party_method_calls: Option<HashMap<String, Identity>>,
47+
48+
// compress_data
49+
compress_data: Option<String>,
4750
}
4851

4952
#[derive(Serialize, Deserialize, Debug)]
@@ -62,14 +65,17 @@ pub struct Struct {
6265
inline_struct: Option<HashMap<String, Identity>>,
6366
#[serde(rename = "Methods")]
6467
methods: Option<HashMap<String, Identity>>,
68+
69+
// compress_data
70+
compress_data: Option<String>,
6571
}
6672

6773
#[derive(Serialize, Deserialize, Debug)]
6874
pub struct Identity {
6975
#[serde(rename = "PkgPath")]
70-
pkg_path: String,
76+
pub pkg_path: String,
7177
#[serde(rename = "Name")]
72-
name: String,
78+
pub name: String,
7379
}
7480

7581
pub fn from_json(json: &str) -> Result<Repository, Box<dyn Error>> {
@@ -78,49 +84,100 @@ pub fn from_json(json: &str) -> Result<Repository, Box<dyn Error>> {
7884
}
7985

8086

87+
pub async fn compress_all(repo: &mut Repository) {
88+
let mut to_compress = Vec::new();
89+
for (_, pkg) in &repo.packages {
90+
for (_, func) in &pkg.functions {
91+
let id = Identity { pkg_path: func.pkg_path.clone(), name: func.name.clone() };
92+
to_compress.push(id)
93+
}
94+
}
95+
96+
for id in to_compress {
97+
cascade_compress_function(&id, repo).await;
98+
}
99+
}
100+
81101
#[async_recursion]
82-
pub async fn cascade_compress_function(func: &mut Function) {
83-
// if func.internal_function_calls.is_none() {
84-
// llm_compress(func);
85-
// return;
86-
// }
87-
//
88-
// for (_, mut f) in func.internal_function_calls.as_mut().unwrap() {
89-
// if f.compress_info.is_none() {
90-
// cascade_compress_function(&mut f).await
91-
// }
92-
// }
93-
//
94-
// llm_compress(func).await;
95-
//
96-
// return;
102+
pub async fn cascade_compress_function(id: &Identity, repo: &mut Repository) {
103+
let mut to_compress = Vec::new();
104+
105+
{
106+
let func_opt = repo.packages.get(id.pkg_path.as_str()).unwrap().functions.get(id.name.as_str());
107+
if func_opt.is_none() {
108+
println!("not found function, id {:?}", id);
109+
}
110+
let func_opt = func_opt.unwrap();
111+
if func_opt.compress_data.is_some() {
112+
println!("{} is already compressed, skip it.", func_opt.name);
113+
return;
114+
}
115+
if let Some(calls) = &func_opt.internal_function_calls {
116+
for (_, f) in calls {
117+
let id = Identity { pkg_path: f.pkg_path.clone(), name: f.name.clone() };
118+
to_compress.push(id);
119+
}
120+
}
121+
122+
if let Some(calls) = &func_opt.internal_method_calls {
123+
for (_, f) in calls {
124+
let id = Identity { pkg_path: f.pkg_path.clone(), name: f.name.clone() };
125+
to_compress.push(id);
126+
}
127+
}
128+
}
129+
130+
for f_id in to_compress {
131+
cascade_compress_function(&f_id, repo).await;
132+
}
133+
134+
let mut map = HashMap::new();
135+
let content = {
136+
let func_opt = repo.packages.get(id.pkg_path.as_str()).unwrap().functions.get(id.name.as_str()).unwrap();
137+
if let Some(calls) = &func_opt.internal_function_calls {
138+
for (k, f) in calls {
139+
let sub_function = repo.packages.get(f.pkg_path.as_str()).unwrap().functions.get(f.name.as_str()).unwrap();
140+
map.insert(k.clone(), sub_function.compress_data.clone().unwrap());
141+
}
142+
}
143+
144+
if let Some(calls) = &func_opt.internal_method_calls {
145+
for (k, f) in calls {
146+
let sub_function = repo.packages.get(f.pkg_path.as_str()).unwrap().functions.get(f.name.as_str()).unwrap();
147+
map.insert(k.clone(), sub_function.compress_data.clone().unwrap());
148+
}
149+
}
150+
151+
println!("start to compress function: {}", func_opt.name);
152+
llm_compress(func_opt.content.as_str(), map).await
153+
};
154+
155+
let mut func_opt = repo.packages.get_mut(id.pkg_path.as_str()).unwrap().functions.get_mut(id.name.as_str()).unwrap();
156+
func_opt.compress_data = content;
97157
}
98158

99-
async fn llm_compress(func: &mut Function) {
100-
// let mut map = HashMap::new(); // 创建一个空的 HashMap
101-
// if func.internal_function_calls.is_some() {
102-
// for (k, ff) in func.internal_function_calls.as_ref().unwrap() {
103-
// map.insert(k.clone(), ff.compress_info.clone().unwrap());
104-
// }
105-
// }
106-
//
107-
// let compress_data = _ollama_compress(func.content.clone(), map).await;
108-
// func.compress_info = Option::from(compress_data);
159+
async fn llm_compress(func: &str, extra: HashMap<String, String>) -> Option<String> {
160+
let compress_data = _ollama_compress(func.to_string(), extra).await;
161+
Option::from(compress_data)
109162
}
110163

111164
pub async fn _ollama_compress(func: String, ctx: HashMap<String, String>) -> String {
112165
let request_url = format!("http://localhost:11434/api/generate");
113166

114-
let mut prompt = r#"You are an engineer who is proficient in Golang. You are responsible for summarizing the functions/methods given by the user.Try to condense output into one sentence and retain key information as much as possible. DO NOT show any codes in your answer. Function/methods content is as follow:"#.to_string();
167+
let mut prompt = r#"You are an engineer who is proficient in Golang. You are responsible for summarizing the functions/methods given by the user, DO NOT put anything that is not mentioned in the function.Try to condense output into one sentence and retain key information as much as possible. DO NOT show any codes in your answer. Function/methods content is as follow:"#.to_string();
115168

116-
prompt.push_str("\n");
169+
prompt.push_str("\n```\n");
117170
prompt.push_str(func.as_str());
118-
prompt.push_str("\nRelated function:\n");
119-
for (name, compressed_data) in ctx {
120-
prompt.push_str(&*(name + ": " + &*compressed_data + "\n"));
171+
prompt.push_str("\n```\n");
172+
if !ctx.is_empty() {
173+
prompt.push_str("\nRelated function:\n");
174+
for (name, compressed_data) in ctx {
175+
prompt.push_str(&*(name + ": " + &*compressed_data + "\n"));
176+
}
121177
}
122178

123179

180+
println!("use prompt:\n{}", prompt);
124181
let req_body: ollama_req = ollama_req { model: "codellama".to_string(), prompt };
125182
let client = reqwest::Client::new();
126183
let mut response = client

0 commit comments

Comments
 (0)