anveesa 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/package.json +1 -1
- package/src/config.rs +5 -0
- package/src/lib.rs +29 -0
- package/src/provider/openai_compatible.rs +11 -3
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
package/package.json
CHANGED
package/src/config.rs
CHANGED
|
@@ -424,6 +424,10 @@ impl ProviderConfig {
|
|
|
424
424
|
pub struct OpenAiCompatibleProviderConfig {
|
|
425
425
|
pub base_url: String,
|
|
426
426
|
|
|
427
|
+
/// Inline API key. Prefer `api_key_env` to avoid storing secrets in the config file.
|
|
428
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
429
|
+
pub api_key: Option<String>,
|
|
430
|
+
|
|
427
431
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
428
432
|
pub api_key_env: Option<String>,
|
|
429
433
|
|
|
@@ -477,6 +481,7 @@ fn insert_openai_provider(
|
|
|
477
481
|
name.to_string(),
|
|
478
482
|
ProviderConfig::OpenAiCompatible(OpenAiCompatibleProviderConfig {
|
|
479
483
|
base_url: base_url.to_string(),
|
|
484
|
+
api_key: None,
|
|
480
485
|
api_key_env: api_key_env.map(str::to_string),
|
|
481
486
|
default_model: None,
|
|
482
487
|
headers: BTreeMap::new(),
|
package/src/lib.rs
CHANGED
|
@@ -1389,6 +1389,24 @@ impl PromptBuffer {
|
|
|
1389
1389
|
self.segments.pop();
|
|
1390
1390
|
}
|
|
1391
1391
|
}
|
|
1392
|
+
|
|
1393
|
+
/// Ctrl+U / Cmd+Delete — erase the entire line.
|
|
1394
|
+
fn clear_all(&mut self) {
|
|
1395
|
+
self.full.clear();
|
|
1396
|
+
self.display.clear();
|
|
1397
|
+
self.segments.clear();
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
/// Ctrl+W / Option+Delete — erase the last word (whitespace-delimited).
|
|
1401
|
+
fn pop_word(&mut self) {
|
|
1402
|
+
// Trim trailing whitespace first, then remove up to the previous whitespace boundary.
|
|
1403
|
+
while self.full.ends_with(' ') {
|
|
1404
|
+
self.pop_last();
|
|
1405
|
+
}
|
|
1406
|
+
while !self.full.is_empty() && !self.full.ends_with(' ') {
|
|
1407
|
+
self.pop_last();
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1392
1410
|
}
|
|
1393
1411
|
|
|
1394
1412
|
#[cfg(unix)]
|
|
@@ -1474,9 +1492,20 @@ fn read_prompt_line(label: &str, width: usize, paste_count: &mut usize) -> Resul
|
|
|
1474
1492
|
}
|
|
1475
1493
|
4 if buffer.is_empty() => return Ok(PromptRead::Eof),
|
|
1476
1494
|
8 | 127 => {
|
|
1495
|
+
// Backspace
|
|
1477
1496
|
buffer.pop_last();
|
|
1478
1497
|
display_rows = redraw_prompt_line(label, &buffer.display, display_rows, width)?;
|
|
1479
1498
|
}
|
|
1499
|
+
21 => {
|
|
1500
|
+
// Ctrl+U / Cmd+Delete — erase entire line
|
|
1501
|
+
buffer.clear_all();
|
|
1502
|
+
display_rows = redraw_prompt_line(label, &buffer.display, display_rows, width)?;
|
|
1503
|
+
}
|
|
1504
|
+
23 => {
|
|
1505
|
+
// Ctrl+W / Option+Delete — erase last word
|
|
1506
|
+
buffer.pop_word();
|
|
1507
|
+
display_rows = redraw_prompt_line(label, &buffer.display, display_rows, width)?;
|
|
1508
|
+
}
|
|
1480
1509
|
0x1b => {
|
|
1481
1510
|
let sequence = read_escape_sequence(&mut input)?;
|
|
1482
1511
|
if sequence == b"[200~" {
|
|
@@ -643,9 +643,17 @@ fn build_headers(config: &OpenAiCompatibleProviderConfig, prompt_cache: bool) ->
|
|
|
643
643
|
let mut headers = HeaderMap::new();
|
|
644
644
|
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
|
|
645
645
|
|
|
646
|
-
if let Some(
|
|
647
|
-
|
|
648
|
-
|
|
646
|
+
let resolved_key = if let Some(key) = &config.api_key {
|
|
647
|
+
Some(key.clone())
|
|
648
|
+
} else if let Some(env_var) = &config.api_key_env {
|
|
649
|
+
Some(
|
|
650
|
+
std::env::var(env_var)
|
|
651
|
+
.with_context(|| format!("environment variable {env_var} is required"))?,
|
|
652
|
+
)
|
|
653
|
+
} else {
|
|
654
|
+
None
|
|
655
|
+
};
|
|
656
|
+
if let Some(api_key) = resolved_key {
|
|
649
657
|
headers.insert(
|
|
650
658
|
AUTHORIZATION,
|
|
651
659
|
HeaderValue::from_str(&format!("Bearer {api_key}"))
|