Skip to content

Commit 0c42321

Browse files
ilblackdragonclaude
andcommitted
fix: address PR review feedback — error handling, dimension validation, libSQL warning
- Replace response.text().await.unwrap_or_default() with proper error propagation in nearai.rs and nearai_chat.rs (4 call sites). Failures now return LlmError::RequestFailed with context instead of silently proceeding with an empty string. - Add embedding dimension validation in OllamaEmbeddings::embed_batch(): returns EmbeddingError if Ollama returns embeddings with a dimension that doesn't match the configured value. - Add runtime warning when libSQL backend is used with non-1536 embedding dimension, since the libSQL schema uses F32_BLOB(1536) and cannot store different-dimension vectors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e285759 commit 0c42321

4 files changed

Lines changed: 60 additions & 4 deletions

File tree

src/llm/nearai.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,10 @@ impl NearAiProvider {
174174
})?;
175175

176176
let status = response.status();
177-
let response_text = response.text().await.unwrap_or_default();
177+
let response_text = response.text().await.map_err(|e| LlmError::RequestFailed {
178+
provider: "nearai".to_string(),
179+
reason: format!("Failed to read response body: {}", e),
180+
})?;
178181

179182
if !status.is_success() {
180183
if status.as_u16() == 401 {
@@ -326,7 +329,10 @@ impl NearAiProvider {
326329
})?;
327330

328331
let status = response.status();
329-
let response_text = response.text().await.unwrap_or_default();
332+
let response_text = response.text().await.map_err(|e| LlmError::RequestFailed {
333+
provider: "nearai".to_string(),
334+
reason: format!("Failed to read response body: {}", e),
335+
})?;
330336

331337
tracing::debug!("NEAR AI response status: {}", status);
332338
tracing::debug!("NEAR AI response body: {}", response_text);

src/llm/nearai_chat.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ impl NearAiChatProvider {
113113
})?;
114114

115115
let status = response.status();
116-
let response_text = response.text().await.unwrap_or_default();
116+
let response_text = response.text().await.map_err(|e| LlmError::RequestFailed {
117+
provider: "nearai_chat".to_string(),
118+
reason: format!("Failed to read response body: {}", e),
119+
})?;
117120

118121
tracing::debug!("NEAR AI Chat response status: {}", status);
119122
tracing::debug!("NEAR AI Chat response body: {}", response_text);
@@ -166,7 +169,10 @@ impl NearAiChatProvider {
166169
})?;
167170

168171
let status = response.status();
169-
let response_text = response.text().await.unwrap_or_default();
172+
let response_text = response.text().await.map_err(|e| LlmError::RequestFailed {
173+
provider: "nearai_chat".to_string(),
174+
reason: format!("Failed to read response body: {}", e),
175+
})?;
170176

171177
if !status.is_success() {
172178
let truncated = crate::agent::truncate_for_preview(&response_text, 512);

src/main.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,23 @@ async fn main() -> anyhow::Result<()> {
141141
None
142142
};
143143

144+
// Warn if libSQL backend is used with non-1536 embedding dimension.
145+
// libSQL schema uses F32_BLOB(1536) which cannot be altered without a
146+
// table rebuild, so non-1536 embeddings will cause storage failures.
147+
if config.database.backend == ironclaw::config::DatabaseBackend::LibSql
148+
&& config.embeddings.enabled
149+
&& config.embeddings.dimension != 1536
150+
{
151+
tracing::warn!(
152+
configured_dimension = config.embeddings.dimension,
153+
"Embedding dimension {} is not 1536. The libSQL schema uses \
154+
F32_BLOB(1536) which requires exactly 1536 dimensions. \
155+
Embedding storage will fail. Use PostgreSQL or set \
156+
EMBEDDING_DIMENSION=1536.",
157+
config.embeddings.dimension
158+
);
159+
}
160+
144161
// Create a Database-trait-backed workspace for the memory command
145162
let db: Arc<dyn ironclaw::db::Database> =
146163
ironclaw::db::connect_from_config(&config.database)
@@ -756,6 +773,21 @@ async fn main() -> anyhow::Result<()> {
756773
None
757774
};
758775

776+
// Warn if libSQL backend is used with non-1536 embedding dimension.
777+
if config.database.backend == ironclaw::config::DatabaseBackend::LibSql
778+
&& config.embeddings.enabled
779+
&& config.embeddings.dimension != 1536
780+
{
781+
tracing::warn!(
782+
configured_dimension = config.embeddings.dimension,
783+
"Embedding dimension {} is not 1536. The libSQL schema uses \
784+
F32_BLOB(1536) which requires exactly 1536 dimensions. \
785+
Embedding storage will fail. Use PostgreSQL or set \
786+
EMBEDDING_DIMENSION=1536.",
787+
config.embeddings.dimension
788+
);
789+
}
790+
759791
// Register memory tools if database is available
760792
if let Some(ref db) = db {
761793
let mut workspace = Workspace::new_with_db("default", Arc::clone(db));

src/workspace/embeddings.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,18 @@ impl EmbeddingProvider for OllamaEmbeddings {
455455
EmbeddingError::InvalidResponse(format!("Failed to parse Ollama response: {}", e))
456456
})?;
457457

458+
// Validate that returned embeddings match the configured dimension.
459+
for (i, emb) in result.embeddings.iter().enumerate() {
460+
if emb.len() != self.dimension {
461+
return Err(EmbeddingError::InvalidResponse(format!(
462+
"Ollama returned embedding of dimension {}, expected {} at index {}",
463+
emb.len(),
464+
self.dimension,
465+
i
466+
)));
467+
}
468+
}
469+
458470
Ok(result.embeddings)
459471
}
460472
}

0 commit comments

Comments
 (0)