Skip to content

Commit 98a1263

Browse files
committed
feat: add backend url route completion (#95)
1 parent 0e95bb3 commit 98a1263

File tree

8 files changed

+81
-20
lines changed

8 files changed

+81
-20
lines changed

crates/custom-types/src/llm_ls.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ impl Backend {
9696
_ => false,
9797
}
9898
}
99+
100+
pub fn url(self) -> String {
101+
match self {
102+
Self::HuggingFace { url } => url,
103+
Self::LlamaCpp { url } => url,
104+
Self::Ollama { url } => url,
105+
Self::OpenAi { url } => url,
106+
Self::Tgi { url } => url,
107+
}
108+
}
99109
}
100110

101111
#[derive(Clone, Debug, Deserialize, Serialize)]
@@ -141,6 +151,8 @@ pub struct GetCompletionsParams {
141151
pub tls_skip_verify_insecure: bool,
142152
#[serde(default)]
143153
pub request_body: Map<String, Value>,
154+
#[serde(default)]
155+
pub disable_url_path_completion: bool,
144156
}
145157

146158
#[derive(Clone, Debug, Deserialize, Serialize)]

crates/llm-ls/src/backend.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl Display for APIError {
2626

2727
#[derive(Debug, Deserialize)]
2828
#[serde(untagged)]
29-
pub enum APIResponse {
29+
pub(crate) enum APIResponse {
3030
Generation(Generation),
3131
Generations(Vec<Generation>),
3232
Error(APIError),

crates/llm-ls/src/document.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ fn get_parser(language_id: LanguageId) -> Result<Parser> {
129129
#[derive(Clone, Debug, Copy)]
130130
/// We redeclare this enum here because the `lsp_types` crate exports a Cow
131131
/// type that is unconvenient to deal with.
132-
pub enum PositionEncodingKind {
132+
pub(crate) enum PositionEncodingKind {
133133
Utf8,
134134
Utf16,
135135
Utf32,
@@ -168,7 +168,7 @@ impl TryFrom<Vec<tower_lsp::lsp_types::PositionEncodingKind>> for PositionEncodi
168168
}
169169

170170
impl PositionEncodingKind {
171-
pub fn to_lsp_type(self) -> tower_lsp::lsp_types::PositionEncodingKind {
171+
pub(crate) fn to_lsp_type(self) -> tower_lsp::lsp_types::PositionEncodingKind {
172172
match self {
173173
PositionEncodingKind::Utf8 => tower_lsp::lsp_types::PositionEncodingKind::UTF8,
174174
PositionEncodingKind::Utf16 => tower_lsp::lsp_types::PositionEncodingKind::UTF16,

crates/llm-ls/src/language_id.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,6 @@ impl fmt::Display for LanguageId {
6262
}
6363
}
6464

65-
pub(crate) struct LanguageIdError {
66-
language_id: String,
67-
}
68-
69-
impl fmt::Display for LanguageIdError {
70-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71-
write!(f, "Invalid language id: {}", self.language_id)
72-
}
73-
}
74-
7565
impl From<&str> for LanguageId {
7666
fn from(value: &str) -> Self {
7767
match value {

crates/llm-ls/src/main.rs

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,15 @@ async fn request_completion(
246246
params.request_body.clone(),
247247
);
248248
let headers = build_headers(&params.backend, params.api_token.as_ref(), params.ide)?;
249+
let url = build_url(
250+
params.backend.clone(),
251+
&params.model,
252+
params.disable_url_path_completion,
253+
);
254+
info!(?headers, url, "sending request to backend");
255+
debug!(?headers, body = ?json, url, "sending request to backend");
249256
let res = http_client
250-
.post(build_url(params.backend.clone(), &params.model))
257+
.post(url)
251258
.json(&json)
252259
.headers(headers)
253260
.send()
@@ -414,7 +421,12 @@ async fn get_tokenizer(
414421
}
415422
}
416423

417-
fn build_url(backend: Backend, model: &str) -> String {
424+
// TODO: add configuration parameter to disable path auto-complete?
425+
fn build_url(backend: Backend, model: &str, disable_url_path_completion: bool) -> String {
426+
if disable_url_path_completion {
427+
return backend.url();
428+
}
429+
418430
match backend {
419431
Backend::HuggingFace { url } => format!("{url}/models/{model}"),
420432
Backend::LlamaCpp { mut url } => {
@@ -428,9 +440,51 @@ fn build_url(backend: Backend, model: &str) -> String {
428440
url
429441
}
430442
}
431-
Backend::Ollama { url } => url,
432-
Backend::OpenAi { url } => url,
433-
Backend::Tgi { url } => url,
443+
Backend::Ollama { mut url } => {
444+
if url.ends_with("/api/generate") {
445+
url
446+
} else if url.ends_with("/api/") {
447+
url.push_str("generate");
448+
url
449+
} else if url.ends_with("/api") {
450+
url.push_str("/generate");
451+
url
452+
} else if url.ends_with('/') {
453+
url.push_str("api/generate");
454+
url
455+
} else {
456+
url.push_str("/api/generate");
457+
url
458+
}
459+
}
460+
Backend::OpenAi { mut url } => {
461+
if url.ends_with("/v1/completions") {
462+
url
463+
} else if url.ends_with("/v1/") {
464+
url.push_str("completions");
465+
url
466+
} else if url.ends_with("/v1") {
467+
url.push_str("/completions");
468+
url
469+
} else if url.ends_with('/') {
470+
url.push_str("v1/completions");
471+
url
472+
} else {
473+
url.push_str("/v1/completions");
474+
url
475+
}
476+
}
477+
Backend::Tgi { mut url } => {
478+
if url.ends_with("/generate") {
479+
url
480+
} else if url.ends_with('/') {
481+
url.push_str("generate");
482+
url
483+
} else {
484+
url.push_str("/generate");
485+
url
486+
}
487+
}
434488
}
435489
}
436490

@@ -466,8 +520,8 @@ impl LlmService {
466520
backend = ?params.backend,
467521
ide = %params.ide,
468522
request_body = serde_json::to_string(&params.request_body).map_err(internal_error)?,
469-
"received completion request for {}",
470-
params.text_document_position.text_document.uri
523+
disable_url_path_completion = params.disable_url_path_completion,
524+
"received completion request",
471525
);
472526
if params.api_token.is_none() && params.backend.is_using_inference_api() {
473527
let now = Instant::now();

crates/testbed/repositories-ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ tls_skip_verify_insecure: false
1616
tokenizer_config:
1717
repository: codellama/CodeLlama-13b-hf
1818
tokens_to_clear: ["<EOT>"]
19+
disable_url_path_completion: false
1920
repositories:
2021
- source:
2122
type: local

crates/testbed/repositories.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ tls_skip_verify_insecure: false
1616
tokenizer_config:
1717
repository: bigcode/starcoder
1818
tokens_to_clear: ["<|endoftext|>"]
19+
disable_url_path_completion: false
1920
repositories:
2021
- source:
2122
type: local

crates/testbed/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ struct RepositoriesConfig {
209209
tokenizer_config: Option<TokenizerConfig>,
210210
tokens_to_clear: Vec<String>,
211211
request_body: Map<String, Value>,
212+
disable_url_path_completion: bool,
212213
}
213214

214215
struct HoleCompletionResult {
@@ -490,6 +491,7 @@ async fn complete_holes(
490491
tokenizer_config,
491492
tokens_to_clear,
492493
request_body,
494+
disable_url_path_completion,
493495
..
494496
} = repos_config;
495497
async move {
@@ -555,6 +557,7 @@ async fn complete_holes(
555557
tokens_to_clear: tokens_to_clear.clone(),
556558
tokenizer_config: tokenizer_config.clone(),
557559
request_body: request_body.clone(),
560+
disable_url_path_completion,
558561
})
559562
.await?;
560563

0 commit comments

Comments
 (0)