@@ -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 ) ]
2020pub 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 ) ]
6874pub 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
7581pub 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
111164pub 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 ( "\n Related 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 ( "\n Related 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