diff --git a/crates/tabby-common/src/api/code.rs b/crates/tabby-common/src/api/code.rs index b458e96ee416..e38fd823ce1e 100644 --- a/crates/tabby-common/src/api/code.rs +++ b/crates/tabby-common/src/api/code.rs @@ -36,7 +36,9 @@ pub struct CodeSearchDocument { pub commit: Option, pub language: String, - pub start_line: usize, + + /// When start line is `None`, it represents the entire file. + pub start_line: Option, } #[derive(Error, Debug)] diff --git a/crates/tabby/src/services/code.rs b/crates/tabby/src/services/code.rs index 7313fcd0007c..e0ebb0d8265c 100644 --- a/crates/tabby/src/services/code.rs +++ b/crates/tabby/src/services/code.rs @@ -205,11 +205,11 @@ async fn create_hit( code::fields::CHUNK_LANGUAGE, ) .to_owned(), - start_line: get_json_number_field( + start_line: Some(get_json_number_field( &doc, schema.field_chunk_attributes, code::fields::CHUNK_START_LINE, - ) as usize, + ) as usize), }; CodeSearchHit { scores, doc } } @@ -325,7 +325,7 @@ mod tests { git_url: "".to_owned(), commit: Some("".to_owned()), language: "".to_owned(), - start_line: 0, + start_line: Some(0), }, }; diff --git a/ee/tabby-db/src/threads.rs b/ee/tabby-db/src/threads.rs index 835ddfdc3bb5..37c46c28144b 100644 --- a/ee/tabby-db/src/threads.rs +++ b/ee/tabby-db/src/threads.rs @@ -81,7 +81,9 @@ pub struct ThreadMessageAttachmentCode { pub language: String, pub filepath: String, pub content: String, - pub start_line: usize, + + /// When start line is `None`, it represents the entire file. + pub start_line: Option, } #[derive(Serialize, Deserialize)] diff --git a/ee/tabby-schema/graphql/schema.graphql b/ee/tabby-schema/graphql/schema.graphql index fef920d952c2..9d35c0ea248a 100644 --- a/ee/tabby-schema/graphql/schema.graphql +++ b/ee/tabby-schema/graphql/schema.graphql @@ -169,7 +169,7 @@ input EmailSettingInput { input MessageAttachmentCodeInput { filepath: String - startLine: Int + "When start line is `None`, it represents the entire file." startLine: Int content: String! } @@ -502,7 +502,8 @@ type MessageAttachmentCode { filepath: String! language: String! content: String! - startLine: Int! + "When start line is `None`, it represents the entire file." + startLine: Int } type MessageAttachmentCodeScores { diff --git a/ee/tabby-schema/src/dao.rs b/ee/tabby-schema/src/dao.rs index 60b7c64c8073..61626d30c5c7 100644 --- a/ee/tabby-schema/src/dao.rs +++ b/ee/tabby-schema/src/dao.rs @@ -206,7 +206,7 @@ impl From for thread::MessageAttachmentCode { filepath: value.filepath, language: value.language, content: value.content, - start_line: value.start_line as i32, + start_line: value.start_line.map(|x| x as i32), } } } @@ -219,7 +219,7 @@ impl From<&thread::MessageAttachmentCode> for ThreadMessageAttachmentCode { filepath: val.filepath.clone(), language: val.language.clone(), content: val.content.clone(), - start_line: val.start_line as usize, + start_line: val.start_line.map(|x| x as usize), } } } diff --git a/ee/tabby-schema/src/schema/thread/inputs.rs b/ee/tabby-schema/src/schema/thread/inputs.rs index 70d7d76edfa0..6e68f49d768c 100644 --- a/ee/tabby-schema/src/schema/thread/inputs.rs +++ b/ee/tabby-schema/src/schema/thread/inputs.rs @@ -143,7 +143,10 @@ pub struct MessageAttachmentInput { #[derive(GraphQLInputObject, Clone)] pub struct MessageAttachmentCodeInput { pub filepath: Option, + + /// When start line is `None`, it represents the entire file. pub start_line: Option, + pub content: String, } diff --git a/ee/tabby-schema/src/schema/thread/types.rs b/ee/tabby-schema/src/schema/thread/types.rs index 240ea5437c69..04f1bad3ecb7 100644 --- a/ee/tabby-schema/src/schema/thread/types.rs +++ b/ee/tabby-schema/src/schema/thread/types.rs @@ -77,7 +77,9 @@ pub struct MessageAttachmentCode { pub filepath: String, pub language: String, pub content: String, - pub start_line: i32, + + /// When start line is `None`, it represents the entire file. + pub start_line: Option, } impl From for MessageAttachmentCode { @@ -88,7 +90,7 @@ impl From for MessageAttachmentCode { filepath: doc.filepath, language: doc.language, content: doc.body, - start_line: doc.start_line as i32, + start_line: doc.start_line.map(|x| x as i32), } } } diff --git a/ee/tabby-webserver/src/service/answer.rs b/ee/tabby-webserver/src/service/answer.rs index 4b7b1a07266b..821b6c5a5a1c 100644 --- a/ee/tabby-webserver/src/service/answer.rs +++ b/ee/tabby-webserver/src/service/answer.rs @@ -596,7 +596,9 @@ pub async fn merge_code_snippets( insert_hit.scores.embedding /= num_files; insert_hit.scores.rrf /= num_files; insert_hit.doc.body = file_content; - insert_hit.doc.start_line = 1; + + // When we use entire file content, mark start_line as None. + insert_hit.doc.start_line = None; result.push(insert_hit); } } else { @@ -772,7 +774,7 @@ mod tests { filepath: "server.py".to_owned(), language: "python".to_owned(), content: "from flask import Flask\n\napp = Flask(__name__)\n\n@app.route('/')\ndef hello():\n return 'Hello, World!'".to_owned(), - start_line: 1, + start_line: Some(1), }], client_code: vec![], }; @@ -806,7 +808,7 @@ mod tests { filepath: "server.py".to_owned(), language: "python".to_owned(), content: "print('Hello, server!')".to_owned(), - start_line: 1, + start_line: Some(1), }], client_code: vec![tabby_schema::thread::MessageAttachmentClientCode { filepath: Some("client.py".to_owned()), @@ -983,7 +985,7 @@ mod tests { filepath: "server.py".to_owned(), language: "python".to_owned(), content: "print('Hello, server!')".to_owned(), - start_line: 1, + start_line: Some(1), }], client_code: vec![tabby_schema::thread::MessageAttachmentClientCode { filepath: Some("client.py".to_owned()), @@ -1045,7 +1047,7 @@ mod tests { filepath: "server.py".to_owned(), language: "python".to_owned(), content: "print('Hello, server!')".to_owned(), - start_line: 1, + start_line: Some(1), }], client_code: vec![tabby_schema::thread::MessageAttachmentClientCode { filepath: Some("client.py".to_owned()), @@ -1341,7 +1343,7 @@ mod tests { git_url: "https://github.com/test/repo.git".to_string(), commit: Some("commit".to_string()), language: "rust".to_string(), - start_line: 1, + start_line: Some(1), }, scores: CodeSearchScores { bm25: 0.5, @@ -1358,7 +1360,7 @@ mod tests { git_url: "https://github.com/test/repo.git".to_string(), commit: Some("commit".to_string()), language: "rust".to_string(), - start_line: 3, + start_line: Some(3), }, scores: CodeSearchScores { bm25: 0.6, diff --git a/ee/tabby-webserver/src/service/answer/testutils/mod.rs b/ee/tabby-webserver/src/service/answer/testutils/mod.rs index db73e60288ba..a189f6cecb7b 100644 --- a/ee/tabby-webserver/src/service/answer/testutils/mod.rs +++ b/ee/tabby-webserver/src/service/answer/testutils/mod.rs @@ -143,7 +143,7 @@ impl CodeSearch for FakeCodeSearch { doc: CodeSearchDocument { filepath: "src/lib.rs".to_string(), body: "fn add(a: i32, b: i32) -> i32 {\n a + b\n}".to_string(), - start_line: 1, + start_line: Some(1), language: "rust".to_string(), file_id: "1".to_string(), chunk_id: "chunk1".to_string(), @@ -160,7 +160,7 @@ impl CodeSearch for FakeCodeSearch { doc: CodeSearchDocument { filepath: "src/main.rs".to_string(), body: "fn main() {\n println!(\"Hello World\");\n}".to_string(), - start_line: 1, + start_line: Some(1), language: "rust".to_string(), file_id: "2".to_string(), chunk_id: "chunk2".to_string(),