diff --git a/clients/tabby-openapi/lib/tabby.d.ts b/clients/tabby-openapi/lib/tabby.d.ts index 061e86407c6..01e4cb46537 100644 --- a/clients/tabby-openapi/lib/tabby.d.ts +++ b/clients/tabby-openapi/lib/tabby.d.ts @@ -257,6 +257,8 @@ export interface components { * * Sorted in descending order of [Snippet::score]. */ relevant_snippets_from_changed_files?: components["schemas"]["Snippet"][] | null; + /** @description The relevant code snippets extracted from recently opened files. These snippets are selected from candidates found within code chunks based on the last visited location. Current Active file is excluded from the search candidates. When provided with [Segments::relevant_snippets_from_changed_files], the snippets have already been deduplicated to ensure no duplication with entries in [Segments::relevant_snippets_from_changed_files]. */ + relevant_snippets_from_recently_opened_files?: components["schemas"]["Snippet"][] | null; /** @description Clipboard content when requesting code completion. */ clipboard?: string | null; }; diff --git a/clients/tabby-openapi/openapi.json b/clients/tabby-openapi/openapi.json index ff570484fd0..2382e69deb6 100644 --- a/clients/tabby-openapi/openapi.json +++ b/clients/tabby-openapi/openapi.json @@ -1 +1 @@ -{"openapi":"3.0.3","info":{"title":"Tabby Server","description":"\n[![tabby stars](https://img.shields.io/github/stars/TabbyML/tabby)](https://github.com/TabbyML/tabby)\n[![Join Slack](https://shields.io/badge/Join-Tabby%20Slack-red?logo=slack)](https://links.tabbyml.com/join-slack)\n\nInstall following IDE / Editor extensions to get started with [Tabby](https://github.com/TabbyML/tabby).\n* [VSCode Extension](https://github.com/TabbyML/tabby/tree/main/clients/vscode) – Install from the [marketplace](https://marketplace.visualstudio.com/items?itemName=TabbyML.vscode-tabby), or [open-vsx.org](https://open-vsx.org/extension/TabbyML/vscode-tabby)\n* [VIM Extension](https://github.com/TabbyML/tabby/tree/main/clients/vim)\n* [IntelliJ Platform Plugin](https://github.com/TabbyML/tabby/tree/main/clients/intellij) – Install from the [marketplace](https://plugins.jetbrains.com/plugin/22379-tabby)\n","contact":{"name":"TabbyML Team"},"license":{"name":"Apache 2.0","url":"https://github.com/TabbyML/tabby/blob/main/LICENSE"},"version":"0.17.0-dev.0"},"servers":[{"url":"/","description":"Server"}],"paths":{"/v1/chat/completions":{"post":{"tags":["v1"],"operationId":"chat_completions","requestBody":{"description":"","content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Success"},"405":{"description":"When chat model is not specified, the endpoint returns 405 Method Not Allowed"},"422":{"description":"When the prompt is malformed, the endpoint returns 422 Unprocessable Entity"}},"security":[{"token":[]}]}},"/v1/completions":{"post":{"tags":["v1"],"operationId":"completion","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionResponse"}}}},"400":{"description":"Bad Request"}},"security":[{"token":[]}]}},"/v1/events":{"post":{"tags":["v1"],"operationId":"event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogEventRequest"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Bad Request"}},"security":[{"token":[]}]}},"/v1/health":{"get":{"tags":["v1"],"operationId":"health","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthState"}}}}},"security":[{"token":[]}]}},"/v1beta/server_setting":{"get":{"tags":["v1beta"],"operationId":"config","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerSetting"}}}}},"security":[{"token":[]}]}}},"components":{"schemas":{"Choice":{"type":"object","required":["index","text"],"properties":{"index":{"type":"integer","format":"int32","minimum":0},"text":{"type":"string"}}},"CodeSearchDocument":{"type":"object","required":["body","filepath","git_url","language","start_line"],"properties":{"body":{"type":"string"},"filepath":{"type":"string"},"git_url":{"type":"string"},"language":{"type":"string"},"start_line":{"type":"integer","minimum":0}}},"CodeSearchHit":{"type":"object","required":["scores","doc"],"properties":{"scores":{"$ref":"#/components/schemas/CodeSearchScores"},"doc":{"$ref":"#/components/schemas/CodeSearchDocument"}}},"CodeSearchQuery":{"type":"object","required":["git_url","content"],"properties":{"git_url":{"type":"string"},"filepath":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"content":{"type":"string"}}},"CodeSearchScores":{"type":"object","required":["rrf","bm25","embedding"],"properties":{"rrf":{"type":"number","format":"float","description":"Reciprocal rank fusion score: https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html"},"bm25":{"type":"number","format":"float"},"embedding":{"type":"number","format":"float"}}},"CompletionRequest":{"type":"object","properties":{"language":{"type":"string","description":"Language identifier, full list is maintained at\nhttps://code.visualstudio.com/docs/languages/identifiers","example":"python","nullable":true},"segments":{"allOf":[{"$ref":"#/components/schemas/Segments"}],"nullable":true},"user":{"type":"string","description":"A unique identifier representing your end-user, which can help Tabby to monitor & generating\nreports.","nullable":true},"debug_options":{"allOf":[{"$ref":"#/components/schemas/DebugOptions"}],"nullable":true},"temperature":{"type":"number","format":"float","description":"The temperature parameter for the model, used to tune variance and \"creativity\" of the model output","nullable":true},"seed":{"type":"integer","format":"int64","description":"The seed used for randomly selecting tokens","nullable":true,"minimum":0}},"example":{"language":"python","segments":{"prefix":"def fib(n):\n ","suffix":"\n return fib(n - 1) + fib(n - 2)"}}},"CompletionResponse":{"type":"object","required":["id","choices"],"properties":{"id":{"type":"string"},"choices":{"type":"array","items":{"$ref":"#/components/schemas/Choice"}},"debug_data":{"allOf":[{"$ref":"#/components/schemas/DebugData"}],"nullable":true}},"example":{"choices":[{"index":0,"text":"string"}],"id":"string"}},"DebugData":{"type":"object","properties":{"snippets":{"type":"array","items":{"$ref":"#/components/schemas/Snippet"},"nullable":true},"prompt":{"type":"string","nullable":true}}},"DebugOptions":{"type":"object","properties":{"raw_prompt":{"type":"string","description":"When `raw_prompt` is specified, it will be passed directly to the inference engine for completion. `segments` field in `CompletionRequest` will be ignored.\n\nThis is useful for certain requests that aim to test the tabby's e2e quality.","nullable":true},"return_snippets":{"type":"boolean","description":"When true, returns `snippets` in `debug_data`."},"return_prompt":{"type":"boolean","description":"When true, returns `prompt` in `debug_data`."},"disable_retrieval_augmented_code_completion":{"type":"boolean","description":"When true, disable retrieval augmented code completion."}}},"Declaration":{"type":"object","description":"A snippet of declaration code that is relevant to the current completion request.","required":["filepath","body"],"properties":{"filepath":{"type":"string","description":"Filepath of the file where the snippet is from.\n- When the file belongs to the same workspace as the current file,\nthis is a relative filepath, use the same rule as [Segments::filepath].\n- When the file located outside the workspace, such as in a dependency package,\nthis is a file URI with an absolute filepath."},"body":{"type":"string","description":"Body of the snippet."}}},"DocSearchDocument":{"type":"object","required":["title","link","snippet"],"properties":{"title":{"type":"string"},"link":{"type":"string"},"snippet":{"type":"string"}}},"DocSearchHit":{"type":"object","required":["score","doc"],"properties":{"score":{"type":"number","format":"float"},"doc":{"$ref":"#/components/schemas/DocSearchDocument"}}},"HealthState":{"type":"object","required":["device","arch","cpu_info","cpu_count","cuda_devices","version"],"properties":{"model":{"type":"string","nullable":true},"chat_model":{"type":"string","nullable":true},"chat_device":{"type":"string","nullable":true},"device":{"type":"string"},"arch":{"type":"string"},"cpu_info":{"type":"string"},"cpu_count":{"type":"integer","minimum":0},"cuda_devices":{"type":"array","items":{"type":"string"}},"version":{"$ref":"#/components/schemas/Version"},"webserver":{"type":"boolean","nullable":true}}},"LogEventRequest":{"type":"object","required":["type","completion_id","choice_index"],"properties":{"type":{"type":"string","description":"Event type, should be `view`, `select` or `dismiss`.","example":"view"},"completion_id":{"type":"string"},"choice_index":{"type":"integer","format":"int32","minimum":0},"view_id":{"type":"string","nullable":true},"elapsed":{"type":"integer","format":"int32","nullable":true,"minimum":0}}},"Segments":{"type":"object","required":["prefix"],"properties":{"prefix":{"type":"string","description":"Content that appears before the cursor in the editor window."},"suffix":{"type":"string","description":"Content that appears after the cursor in the editor window.","nullable":true},"filepath":{"type":"string","description":"The relative path of the file that is being edited.\n- When [Segments::git_url] is set, this is the path of the file in the git repository.\n- When [Segments::git_url] is empty, this is the path of the file in the workspace.","nullable":true},"git_url":{"type":"string","description":"The remote URL of the current git repository.\nLeave this empty if the file is not in a git repository,\nor the git repository does not have a remote URL.","nullable":true},"declarations":{"type":"array","items":{"$ref":"#/components/schemas/Declaration"},"description":"The relevant declaration code snippets provided by the editor's LSP,\ncontain declarations of symbols extracted from [Segments::prefix].","nullable":true},"relevant_snippets_from_changed_files":{"type":"array","items":{"$ref":"#/components/schemas/Snippet"},"description":"The relevant code snippets extracted from recently edited files.\nThese snippets are selected from candidates found within code chunks\nbased on the edited location.\nThe current editing file is excluded from the search candidates.\n\nWhen provided alongside [Segments::declarations], the snippets have\nalready been deduplicated to ensure no duplication with entries\nin [Segments::declarations].\n\nSorted in descending order of [Snippet::score].","nullable":true},"clipboard":{"type":"string","description":"Clipboard content when requesting code completion.","nullable":true}}},"ServerSetting":{"type":"object","required":["disable_client_side_telemetry"],"properties":{"disable_client_side_telemetry":{"type":"boolean"}}},"Snippet":{"type":"object","required":["filepath","body","score"],"properties":{"filepath":{"type":"string"},"body":{"type":"string"},"score":{"type":"number","format":"float"}}},"Version":{"type":"object","required":["build_date","build_timestamp","git_sha","git_describe"],"properties":{"build_date":{"type":"string"},"build_timestamp":{"type":"string"},"git_sha":{"type":"string"},"git_describe":{"type":"string"}}}},"securitySchemes":{"token":{"type":"http","scheme":"bearer","bearerFormat":"token"}}}} \ No newline at end of file +{"openapi":"3.0.3","info":{"title":"Tabby Server","description":"\n[![tabby stars](https://img.shields.io/github/stars/TabbyML/tabby)](https://github.com/TabbyML/tabby)\n[![Join Slack](https://shields.io/badge/Join-Tabby%20Slack-red?logo=slack)](https://links.tabbyml.com/join-slack)\n\nInstall following IDE / Editor extensions to get started with [Tabby](https://github.com/TabbyML/tabby).\n* [VSCode Extension](https://github.com/TabbyML/tabby/tree/main/clients/vscode) – Install from the [marketplace](https://marketplace.visualstudio.com/items?itemName=TabbyML.vscode-tabby), or [open-vsx.org](https://open-vsx.org/extension/TabbyML/vscode-tabby)\n* [VIM Extension](https://github.com/TabbyML/tabby/tree/main/clients/vim)\n* [IntelliJ Platform Plugin](https://github.com/TabbyML/tabby/tree/main/clients/intellij) – Install from the [marketplace](https://plugins.jetbrains.com/plugin/22379-tabby)\n","contact":{"name":"TabbyML Team"},"license":{"name":"Apache 2.0","url":"https://github.com/TabbyML/tabby/blob/main/LICENSE"},"version":"0.17.0-dev.0"},"servers":[{"url":"/","description":"Server"}],"paths":{"/v1/chat/completions":{"post":{"tags":["v1"],"operationId":"chat_completions","requestBody":{"description":"","content":{"application/json":{"schema":{}}},"required":true},"responses":{"200":{"description":"Success"},"405":{"description":"When chat model is not specified, the endpoint returns 405 Method Not Allowed"},"422":{"description":"When the prompt is malformed, the endpoint returns 422 Unprocessable Entity"}},"security":[{"token":[]}]}},"/v1/completions":{"post":{"tags":["v1"],"operationId":"completion","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletionResponse"}}}},"400":{"description":"Bad Request"}},"security":[{"token":[]}]}},"/v1/events":{"post":{"tags":["v1"],"operationId":"event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogEventRequest"}}},"required":true},"responses":{"200":{"description":"Success"},"400":{"description":"Bad Request"}},"security":[{"token":[]}]}},"/v1/health":{"get":{"tags":["v1"],"operationId":"health","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthState"}}}}},"security":[{"token":[]}]}},"/v1beta/server_setting":{"get":{"tags":["v1beta"],"operationId":"config","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerSetting"}}}}},"security":[{"token":[]}]}}},"components":{"schemas":{"Choice":{"type":"object","required":["index","text"],"properties":{"index":{"type":"integer","format":"int32","minimum":0},"text":{"type":"string"}}},"CodeSearchDocument":{"type":"object","required":["body","filepath","git_url","language","start_line"],"properties":{"body":{"type":"string"},"filepath":{"type":"string"},"git_url":{"type":"string"},"language":{"type":"string"},"start_line":{"type":"integer","minimum":0}}},"CodeSearchHit":{"type":"object","required":["scores","doc"],"properties":{"scores":{"$ref":"#/components/schemas/CodeSearchScores"},"doc":{"$ref":"#/components/schemas/CodeSearchDocument"}}},"CodeSearchQuery":{"type":"object","required":["git_url","content"],"properties":{"git_url":{"type":"string"},"filepath":{"type":"string","nullable":true},"language":{"type":"string","nullable":true},"content":{"type":"string"}}},"CodeSearchScores":{"type":"object","required":["rrf","bm25","embedding"],"properties":{"rrf":{"type":"number","format":"float","description":"Reciprocal rank fusion score: https://www.elastic.co/guide/en/elasticsearch/reference/current/rrf.html"},"bm25":{"type":"number","format":"float"},"embedding":{"type":"number","format":"float"}}},"CompletionRequest":{"type":"object","properties":{"language":{"type":"string","description":"Language identifier, full list is maintained at\nhttps://code.visualstudio.com/docs/languages/identifiers","example":"python","nullable":true},"segments":{"allOf":[{"$ref":"#/components/schemas/Segments"}],"nullable":true},"user":{"type":"string","description":"A unique identifier representing your end-user, which can help Tabby to monitor & generating\nreports.","nullable":true},"debug_options":{"allOf":[{"$ref":"#/components/schemas/DebugOptions"}],"nullable":true},"temperature":{"type":"number","format":"float","description":"The temperature parameter for the model, used to tune variance and \"creativity\" of the model output","nullable":true},"seed":{"type":"integer","format":"int64","description":"The seed used for randomly selecting tokens","nullable":true,"minimum":0}},"example":{"language":"python","segments":{"prefix":"def fib(n):\n ","suffix":"\n return fib(n - 1) + fib(n - 2)"}}},"CompletionResponse":{"type":"object","required":["id","choices"],"properties":{"id":{"type":"string"},"choices":{"type":"array","items":{"$ref":"#/components/schemas/Choice"}},"debug_data":{"allOf":[{"$ref":"#/components/schemas/DebugData"}],"nullable":true}},"example":{"choices":[{"index":0,"text":"string"}],"id":"string"}},"DebugData":{"type":"object","properties":{"snippets":{"type":"array","items":{"$ref":"#/components/schemas/Snippet"},"nullable":true},"prompt":{"type":"string","nullable":true}}},"DebugOptions":{"type":"object","properties":{"raw_prompt":{"type":"string","description":"When `raw_prompt` is specified, it will be passed directly to the inference engine for completion. `segments` field in `CompletionRequest` will be ignored.\n\nThis is useful for certain requests that aim to test the tabby's e2e quality.","nullable":true},"return_snippets":{"type":"boolean","description":"When true, returns `snippets` in `debug_data`."},"return_prompt":{"type":"boolean","description":"When true, returns `prompt` in `debug_data`."},"disable_retrieval_augmented_code_completion":{"type":"boolean","description":"When true, disable retrieval augmented code completion."}}},"Declaration":{"type":"object","description":"A snippet of declaration code that is relevant to the current completion request.","required":["filepath","body"],"properties":{"filepath":{"type":"string","description":"Filepath of the file where the snippet is from.\n- When the file belongs to the same workspace as the current file,\nthis is a relative filepath, use the same rule as [Segments::filepath].\n- When the file located outside the workspace, such as in a dependency package,\nthis is a file URI with an absolute filepath."},"body":{"type":"string","description":"Body of the snippet."}}},"DocSearchDocument":{"type":"object","required":["title","link","snippet"],"properties":{"title":{"type":"string"},"link":{"type":"string"},"snippet":{"type":"string"}}},"DocSearchHit":{"type":"object","required":["score","doc"],"properties":{"score":{"type":"number","format":"float"},"doc":{"$ref":"#/components/schemas/DocSearchDocument"}}},"HealthState":{"type":"object","required":["device","arch","cpu_info","cpu_count","cuda_devices","version"],"properties":{"model":{"type":"string","nullable":true},"chat_model":{"type":"string","nullable":true},"chat_device":{"type":"string","nullable":true},"device":{"type":"string"},"arch":{"type":"string"},"cpu_info":{"type":"string"},"cpu_count":{"type":"integer","minimum":0},"cuda_devices":{"type":"array","items":{"type":"string"}},"version":{"$ref":"#/components/schemas/Version"},"webserver":{"type":"boolean","nullable":true}}},"LogEventRequest":{"type":"object","required":["type","completion_id","choice_index"],"properties":{"type":{"type":"string","description":"Event type, should be `view`, `select` or `dismiss`.","example":"view"},"completion_id":{"type":"string"},"choice_index":{"type":"integer","format":"int32","minimum":0},"view_id":{"type":"string","nullable":true},"elapsed":{"type":"integer","format":"int32","nullable":true,"minimum":0}}},"Segments":{"type":"object","required":["prefix"],"properties":{"prefix":{"type":"string","description":"Content that appears before the cursor in the editor window."},"suffix":{"type":"string","description":"Content that appears after the cursor in the editor window.","nullable":true},"filepath":{"type":"string","description":"The relative path of the file that is being edited.\n- When [Segments::git_url] is set, this is the path of the file in the git repository.\n- When [Segments::git_url] is empty, this is the path of the file in the workspace.","nullable":true},"git_url":{"type":"string","description":"The remote URL of the current git repository.\nLeave this empty if the file is not in a git repository,\nor the git repository does not have a remote URL.","nullable":true},"declarations":{"type":"array","items":{"$ref":"#/components/schemas/Declaration"},"description":"The relevant declaration code snippets provided by the editor's LSP,\ncontain declarations of symbols extracted from [Segments::prefix].","nullable":true},"relevant_snippets_from_changed_files":{"type":"array","items":{"$ref":"#/components/schemas/Snippet"},"description":"The relevant code snippets extracted from recently edited files.\nThese snippets are selected from candidates found within code chunks\nbased on the edited location.\nThe current editing file is excluded from the search candidates.\n\nWhen provided alongside [Segments::declarations], the snippets have\nalready been deduplicated to ensure no duplication with entries\nin [Segments::declarations].\n\nSorted in descending order of [Snippet::score].","nullable":true},"relevant_snippets_from_recently_opened_files": {"type": "array","items": {"$ref": "#/components/schemas/Snippet"},"description": "The relevant code snippets extracted from recently opened files. These snippets are selected from candidates found within code chunks based on the last visited location. Current Active file is excluded from the search candidates. When provided with [Segments::relevant_snippets_from_changed_files], the snippets have already been deduplicated to ensure no duplication with entries in [Segments::relevant_snippets_from_changed_files].","nullable": true},"clipboard":{"type":"string","description":"Clipboard content when requesting code completion.","nullable":true}}},"ServerSetting":{"type":"object","required":["disable_client_side_telemetry"],"properties":{"disable_client_side_telemetry":{"type":"boolean"}}},"Snippet":{"type":"object","required":["filepath","body","score"],"properties":{"filepath":{"type":"string"},"body":{"type":"string"},"score":{"type":"number","format":"float"}}},"Version":{"type":"object","required":["build_date","build_timestamp","git_sha","git_describe"],"properties":{"build_date":{"type":"string"},"build_timestamp":{"type":"string"},"git_sha":{"type":"string"},"git_describe":{"type":"string"}}}},"securitySchemes":{"token":{"type":"http","scheme":"bearer","bearerFormat":"token"}}}} \ No newline at end of file diff --git a/crates/tabby/src/services/completion.rs b/crates/tabby/src/services/completion.rs index b489dd15978..c713bb6ae53 100644 --- a/crates/tabby/src/services/completion.rs +++ b/crates/tabby/src/services/completion.rs @@ -136,6 +136,16 @@ pub struct Segments { /// Sorted in descending order of [Snippet::score]. relevant_snippets_from_changed_files: Option>, + /// The relevant code snippets extracted from recently opened files. + /// These snippets are selected from candidates found within code chunks + /// based on the last visited location. + /// + /// Current Active file is excluded from the search candidates. + /// When provided with [Segments::relevant_snippets_from_changed_files], the snippets have + /// already been deduplicated to ensure no duplication with entries + /// in [Segments::relevant_snippets_from_changed_files]. + relevant_snippets_from_recently_opened_files: Option>, + /// Clipboard content when requesting code completion. clipboard: Option, } @@ -456,6 +466,7 @@ mod tests { git_url: None, declarations: None, relevant_snippets_from_changed_files: None, + relevant_snippets_from_recently_opened_files: None, clipboard: None, }; let request = CompletionRequest { diff --git a/crates/tabby/src/services/completion/completion_prompt.rs b/crates/tabby/src/services/completion/completion_prompt.rs index 8bcbd8f3d0b..622f9f76d9e 100644 --- a/crates/tabby/src/services/completion/completion_prompt.rs +++ b/crates/tabby/src/services/completion/completion_prompt.rs @@ -155,7 +155,6 @@ fn extract_snippets_from_segments( if count_characters + declaration.body.len() > max_snippets_chars { break; } - count_characters += declaration.body.len(); ret.push(Snippet { filepath: declaration.filepath.clone(), @@ -181,6 +180,22 @@ fn extract_snippets_from_segments( } } + // then comes to the snippets from recently opened files. + if let Some(relevant_snippets) = &segments.relevant_snippets_from_recently_opened_files { + for snippet in relevant_snippets { + if count_characters + snippet.body.len() > max_snippets_chars { + break; + } + + count_characters += snippet.body.len(); + ret.push(Snippet { + filepath: snippet.filepath.clone(), + body: snippet.body.clone(), + score: 1.0, + }); + } + } + if ret.is_empty() { None } else { @@ -276,6 +291,7 @@ mod tests { git_url: None, declarations: None, relevant_snippets_from_changed_files: None, + relevant_snippets_from_recently_opened_files: None, clipboard: None, } } @@ -496,6 +512,7 @@ def this_is_prefix():\n"; git_url: None, declarations: None, relevant_snippets_from_changed_files: None, + relevant_snippets_from_recently_opened_files: None, clipboard: None, }; @@ -517,12 +534,17 @@ def this_is_prefix():\n"; body: "res_1 = invoke_function_1(n)".to_owned(), score: 1.0, }]), + relevant_snippets_from_recently_opened_files: Some(vec![Snippet { + filepath: "b1.py".to_owned(), + body: "res_1 = invoke_function_1(n)".to_owned(), + score: 1.0, + }]), clipboard: None, }; assert!( extract_snippets_from_segments(max_snippets_chars, &segments) - .is_some_and(|x| x.1.len() == 2) + .is_some_and(|x| x.1.len() == 3) ); } }