fix(security): resolve rebase conflicts and provider regressions
This commit is contained in:
parent
5d131a8903
commit
0087bcc496
4 changed files with 23 additions and 44 deletions
|
|
@ -281,16 +281,12 @@ fn parse_sse_line(line: &str) -> StreamResult<Option<String>> {
|
|||
}
|
||||
|
||||
/// Convert SSE byte stream to text chunks.
|
||||
async fn sse_bytes_to_chunks(
|
||||
mut response: reqwest::Response,
|
||||
fn sse_bytes_to_chunks(
|
||||
response: reqwest::Response,
|
||||
count_tokens: bool,
|
||||
) -> stream::BoxStream<'static, StreamResult<StreamChunk>> {
|
||||
use tokio::io::AsyncBufReadExt;
|
||||
|
||||
let name = "stream".to_string();
|
||||
|
||||
// Create a channel to send chunks
|
||||
let (mut tx, rx) = tokio::sync::mpsc::channel::<StreamResult<StreamChunk>>(100);
|
||||
let (tx, rx) = tokio::sync::mpsc::channel::<StreamResult<StreamChunk>>(100);
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Buffer for incomplete lines
|
||||
|
|
@ -341,10 +337,7 @@ async fn sse_bytes_to_chunks(
|
|||
return; // Receiver dropped
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
// Empty line or [DONE] sentinel - continue
|
||||
continue;
|
||||
}
|
||||
Ok(None) => {}
|
||||
Err(e) => {
|
||||
let _ = tx.send(Err(e)).await;
|
||||
return;
|
||||
|
|
@ -365,10 +358,7 @@ async fn sse_bytes_to_chunks(
|
|||
|
||||
// Convert channel receiver to stream
|
||||
stream::unfold(rx, |mut rx| async {
|
||||
match rx.recv().await {
|
||||
Some(chunk) => Some((chunk, rx)),
|
||||
None => None,
|
||||
}
|
||||
rx.recv().await.map(|chunk| (chunk, rx))
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
|
@ -692,7 +682,7 @@ impl Provider for OpenAiCompatibleProvider {
|
|||
temperature: f64,
|
||||
options: StreamOptions,
|
||||
) -> stream::BoxStream<'static, StreamResult<StreamChunk>> {
|
||||
let api_key = match self.api_key.as_ref() {
|
||||
let credential = match self.credential.as_ref() {
|
||||
Some(key) => key.clone(),
|
||||
None => {
|
||||
let provider_name = self.name.clone();
|
||||
|
|
@ -739,10 +729,10 @@ impl Provider for OpenAiCompatibleProvider {
|
|||
// Apply auth header
|
||||
req_builder = match &auth_header {
|
||||
AuthStyle::Bearer => {
|
||||
req_builder.header("Authorization", format!("Bearer {}", api_key))
|
||||
req_builder.header("Authorization", format!("Bearer {}", credential))
|
||||
}
|
||||
AuthStyle::XApiKey => req_builder.header("x-api-key", &api_key),
|
||||
AuthStyle::Custom(header) => req_builder.header(header, &api_key),
|
||||
AuthStyle::XApiKey => req_builder.header("x-api-key", &credential),
|
||||
AuthStyle::Custom(header) => req_builder.header(header, &credential),
|
||||
};
|
||||
|
||||
// Set accept header for streaming
|
||||
|
|
@ -771,7 +761,7 @@ impl Provider for OpenAiCompatibleProvider {
|
|||
}
|
||||
|
||||
// Convert to chunk stream and forward to channel
|
||||
let mut chunk_stream = sse_bytes_to_chunks(response, options.count_tokens).await;
|
||||
let mut chunk_stream = sse_bytes_to_chunks(response, options.count_tokens);
|
||||
while let Some(chunk) = chunk_stream.next().await {
|
||||
if tx.send(chunk).await.is_err() {
|
||||
break; // Receiver dropped
|
||||
|
|
@ -781,10 +771,7 @@ impl Provider for OpenAiCompatibleProvider {
|
|||
|
||||
// Convert channel receiver to stream
|
||||
stream::unfold(rx, |mut rx| async move {
|
||||
match rx.recv().await {
|
||||
Some(chunk) => Some((chunk, rx)),
|
||||
None => None,
|
||||
}
|
||||
rx.recv().await.map(|chunk| (chunk, rx))
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ impl Provider for OpenRouterProvider {
|
|||
model: &str,
|
||||
temperature: f64,
|
||||
) -> anyhow::Result<ProviderChatResponse> {
|
||||
let api_key = self.api_key.as_ref().ok_or_else(|| {
|
||||
let credential = self.credential.as_ref().ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"OpenRouter API key not set. Run `zeroclaw onboard` or set OPENROUTER_API_KEY env var."
|
||||
)
|
||||
|
|
@ -462,7 +462,7 @@ impl Provider for OpenRouterProvider {
|
|||
let response = self
|
||||
.client
|
||||
.post("https://openrouter.ai/api/v1/chat/completions")
|
||||
.header("Authorization", format!("Bearer {api_key}"))
|
||||
.header("Authorization", format!("Bearer {credential}"))
|
||||
.header(
|
||||
"HTTP-Referer",
|
||||
"https://github.com/theonlyhennygod/zeroclaw",
|
||||
|
|
|
|||
|
|
@ -329,21 +329,11 @@ pub trait Provider: Send + Sync {
|
|||
/// Default implementation falls back to stream_chat_with_system with last user message.
|
||||
fn stream_chat_with_history(
|
||||
&self,
|
||||
messages: &[ChatMessage],
|
||||
model: &str,
|
||||
temperature: f64,
|
||||
options: StreamOptions,
|
||||
_messages: &[ChatMessage],
|
||||
_model: &str,
|
||||
_temperature: f64,
|
||||
_options: StreamOptions,
|
||||
) -> stream::BoxStream<'static, StreamResult<StreamChunk>> {
|
||||
let system = messages
|
||||
.iter()
|
||||
.find(|m| m.role == "system")
|
||||
.map(|m| m.content.clone());
|
||||
let last_user = messages
|
||||
.iter()
|
||||
.rfind(|m| m.role == "user")
|
||||
.map(|m| m.content.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
// For default implementation, we need to convert to owned strings
|
||||
// This is a limitation of the default implementation
|
||||
let provider_name = "unknown".to_string();
|
||||
|
|
|
|||
|
|
@ -94,14 +94,16 @@ impl Tool for HardwareMemoryReadTool {
|
|||
.get("address")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("0x20000000");
|
||||
let address = parse_hex_address(address_str).unwrap_or(NUCLEO_RAM_BASE);
|
||||
let _address = parse_hex_address(address_str).unwrap_or(NUCLEO_RAM_BASE);
|
||||
|
||||
let length = args.get("length").and_then(|v| v.as_u64()).unwrap_or(128) as usize;
|
||||
let length = length.min(256).max(1);
|
||||
let requested_length = args.get("length").and_then(|v| v.as_u64()).unwrap_or(128);
|
||||
let _length = usize::try_from(requested_length)
|
||||
.unwrap_or(256)
|
||||
.clamp(1, 256);
|
||||
|
||||
#[cfg(feature = "probe")]
|
||||
{
|
||||
match probe_read_memory(chip.unwrap(), address, length) {
|
||||
match probe_read_memory(chip.unwrap(), _address, _length) {
|
||||
Ok(output) => {
|
||||
return Ok(ToolResult {
|
||||
success: true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue