Fixing code warnings

This commit is contained in:
Timmy
2026-03-24 21:26:48 +00:00
parent df6d2db327
commit 721d12bcfe
3 changed files with 45 additions and 52 deletions

View File

@@ -15,9 +15,6 @@ use async_trait::async_trait;
/// producing and consuming these identifiers.
pub type MessageId = String;
/// A platform-agnostic identifier for a chat room / channel / conversation.
pub type RoomId = String;
/// Abstraction over a chat platform's message-sending capabilities.
///
/// Implementations must be `Send + Sync` so they can be shared across

View File

@@ -15,8 +15,8 @@ use tokio::sync::Mutex as TokioMutex;
use crate::agents::AgentPool;
use crate::chat::transport::matrix::{ConversationEntry, ConversationRole, RoomConversation};
use crate::slog;
use crate::chat::{ChatTransport, MessageId};
use crate::slog;
// ── API base URLs (overridable for tests) ────────────────────────────────
@@ -46,6 +46,7 @@ const OUTSIDE_WINDOW_ERR: &str = "OUTSIDE_MESSAGING_WINDOW";
/// between free-form text and a template message.
pub struct MessagingWindowTracker {
last_message: std::sync::Mutex<HashMap<String, std::time::Instant>>,
#[allow(dead_code)] // Used by Meta provider path (is_within_window → send_notification)
window_duration: std::time::Duration,
}
@@ -83,6 +84,7 @@ impl MessagingWindowTracker {
/// Returns `true` when the last inbound message from `phone` arrived within
/// the 24-hour window, meaning free-form replies are still permitted.
#[allow(dead_code)] // Used by Meta provider path (send_notification)
pub fn is_within_window(&self, phone: &str) -> bool {
let map = self.last_message.lock().unwrap();
match map.get(phone) {
@@ -105,6 +107,7 @@ pub struct WhatsAppTransport {
client: reqwest::Client,
/// Name of the approved Meta message template used for notifications
/// outside the 24-hour messaging window.
#[allow(dead_code)] // Used by Meta provider path (send_template_notification)
notification_template_name: String,
/// Optional base URL override for tests.
api_base: String,
@@ -126,11 +129,7 @@ impl WhatsAppTransport {
}
#[cfg(test)]
fn with_api_base(
phone_number_id: String,
access_token: String,
api_base: String,
) -> Self {
fn with_api_base(phone_number_id: String, access_token: String, api_base: String) -> Self {
Self {
phone_number_id,
access_token,
@@ -209,6 +208,7 @@ impl WhatsAppTransport {
///
/// The template body is expected to accept two positional parameters:
/// `{{1}}` = story name, `{{2}}` = pipeline stage.
#[allow(dead_code)] // Meta provider path — template fallback for expired 24h window
pub async fn send_template_notification(
&self,
to: &str,
@@ -282,6 +282,7 @@ impl WhatsAppTransport {
///
/// This method never crashes on a messaging-window error — it always
/// attempts the template fallback and logs what happened.
#[allow(dead_code)] // Meta provider path — window-aware notification dispatch
pub async fn send_notification(
&self,
to: &str,
@@ -423,7 +424,11 @@ impl TwilioWhatsAppTransport {
format!("whatsapp:{}", to)
};
let params = [("From", from.as_str()), ("To", to_wa.as_str()), ("Body", body)];
let params = [
("From", from.as_str()),
("To", to_wa.as_str()),
("Body", body),
];
let resp = self
.client
@@ -444,9 +449,8 @@ impl TwilioWhatsAppTransport {
return Err(format!("Twilio API returned {status}: {resp_text}"));
}
let parsed: TwilioSendResponse = serde_json::from_str(&resp_text).map_err(|e| {
format!("Failed to parse Twilio API response: {e} — body: {resp_text}")
})?;
let parsed: TwilioSendResponse = serde_json::from_str(&resp_text)
.map_err(|e| format!("Failed to parse Twilio API response: {e} — body: {resp_text}"))?;
Ok(parsed.sid.unwrap_or_default())
}
@@ -472,7 +476,9 @@ impl ChatTransport for TwilioWhatsAppTransport {
html: &str,
) -> Result<(), String> {
// Twilio does not support message editing — send a new message.
slog!("[whatsapp/twilio] edit_message — Twilio does not support edits, sending new message");
slog!(
"[whatsapp/twilio] edit_message — Twilio does not support edits, sending new message"
);
self.send_message(recipient, plain, html).await.map(|_| ())
}
@@ -525,10 +531,7 @@ pub fn extract_twilio_text_messages(bytes: &[u8]) -> Vec<(String, String)> {
};
// Strip the "whatsapp:" prefix so the sender is stored as a plain phone number.
let sender = from
.strip_prefix("whatsapp:")
.unwrap_or(&from)
.to_string();
let sender = from.strip_prefix("whatsapp:").unwrap_or(&from).to_string();
vec![(sender, body)]
}
@@ -575,6 +578,7 @@ struct GraphApiError {
// ── Template message types ──────────────────────────────────────────────
#[allow(dead_code)] // Meta provider path — template message types
#[derive(Serialize)]
struct GraphTemplateMessage<'a> {
messaging_product: &'a str,
@@ -583,6 +587,7 @@ struct GraphTemplateMessage<'a> {
template: GraphTemplate<'a>,
}
#[allow(dead_code)]
#[derive(Serialize)]
struct GraphTemplate<'a> {
name: &'a str,
@@ -590,17 +595,20 @@ struct GraphTemplate<'a> {
components: Vec<GraphTemplateComponent>,
}
#[allow(dead_code)]
#[derive(Serialize)]
struct GraphLanguage {
code: &'static str,
}
#[allow(dead_code)]
#[derive(Serialize)]
struct GraphTemplateComponent {
r#type: &'static str,
parameters: Vec<GraphTemplateParameter>,
}
#[allow(dead_code)]
#[derive(Serialize)]
struct GraphTemplateParameter {
r#type: &'static str,
@@ -631,11 +639,13 @@ pub struct WebhookChange {
pub struct WebhookValue {
#[serde(default)]
pub messages: Vec<WebhookMessage>,
#[allow(dead_code)] // Present in Meta webhook JSON, kept for deserialization
pub metadata: Option<WebhookMetadata>,
}
#[derive(Deserialize, Debug)]
pub struct WebhookMetadata {
#[allow(dead_code)]
pub phone_number_id: Option<String>,
}
@@ -733,9 +743,7 @@ struct PersistedWhatsAppHistory {
const WHATSAPP_HISTORY_FILE: &str = ".storkit/whatsapp_history.json";
/// Load WhatsApp conversation history from disk.
pub fn load_whatsapp_history(
project_root: &std::path::Path,
) -> HashMap<String, RoomConversation> {
pub fn load_whatsapp_history(project_root: &std::path::Path) -> HashMap<String, RoomConversation> {
let path = project_root.join(WHATSAPP_HISTORY_FILE);
let data = match std::fs::read_to_string(&path) {
Ok(d) => d,
@@ -828,9 +836,7 @@ pub async fn webhook_verify(
&& let Some(challenge) = q.hub_challenge
{
slog!("[whatsapp] Webhook verification succeeded");
return Response::builder()
.status(StatusCode::OK)
.body(challenge);
return Response::builder().status(StatusCode::OK).body(challenge);
}
slog!("[whatsapp] Webhook verification failed");
Response::builder()
@@ -897,17 +903,11 @@ pub async fn webhook_receive(
}
});
Response::builder()
.status(StatusCode::OK)
.body("ok")
Response::builder().status(StatusCode::OK).body("ok")
}
/// Dispatch an incoming WhatsApp message to bot commands.
async fn handle_incoming_message(
ctx: &WhatsAppWebhookContext,
sender: &str,
message: &str,
) {
async fn handle_incoming_message(ctx: &WhatsAppWebhookContext, sender: &str, message: &str) {
use crate::chat::transport::matrix::commands::{CommandDispatch, try_handle_command};
// Record this inbound message to keep the 24-hour window open.
@@ -950,12 +950,12 @@ async fn handle_incoming_message(
HtopCommand::Start { duration_secs } => {
// On WhatsApp, send a single snapshot instead of a live-updating
// dashboard since we can't edit messages.
let snapshot =
crate::chat::transport::matrix::htop::build_htop_message(&ctx.agents, 0, duration_secs);
let _ = ctx
.transport
.send_message(sender, &snapshot, "")
.await;
let snapshot = crate::chat::transport::matrix::htop::build_htop_message(
&ctx.agents,
0,
duration_secs,
);
let _ = ctx.transport.send_message(sender, &snapshot, "").await;
}
}
return;
@@ -991,22 +991,16 @@ async fn handle_incoming_message(
}
/// Forward a message to Claude Code and send the response back via WhatsApp.
async fn handle_llm_message(
ctx: &WhatsAppWebhookContext,
sender: &str,
user_message: &str,
) {
use crate::llm::providers::claude_code::{ClaudeCodeProvider, ClaudeCodeResult};
async fn handle_llm_message(ctx: &WhatsAppWebhookContext, sender: &str, user_message: &str) {
use crate::chat::transport::matrix::drain_complete_paragraphs;
use crate::llm::providers::claude_code::{ClaudeCodeProvider, ClaudeCodeResult};
use std::sync::atomic::{AtomicBool, Ordering};
use tokio::sync::watch;
// Look up existing session ID for this sender.
let resume_session_id: Option<String> = {
let guard = ctx.history.lock().await;
guard
.get(sender)
.and_then(|conv| conv.session_id.clone())
guard.get(sender).and_then(|conv| conv.session_id.clone())
};
let bot_name = &ctx.bot_name;
@@ -1077,9 +1071,7 @@ async fn handle_llm_message(
let last_text = messages
.iter()
.rev()
.find(|m| {
m.role == crate::llm::types::Role::Assistant && !m.content.is_empty()
})
.find(|m| m.role == crate::llm::types::Role::Assistant && !m.content.is_empty())
.map(|m| m.content.clone())
.unwrap_or_default();
if !last_text.is_empty() {
@@ -1220,7 +1212,10 @@ mod tests {
let result = transport.send_message("15551234567", "hello", "").await;
assert!(result.is_err());
let msg = result.unwrap_err();
assert!(msg.contains("24-hour messaging window"), "unexpected: {msg}");
assert!(
msg.contains("24-hour messaging window"),
"unexpected: {msg}"
);
}
// ── send_template_notification ────────────────────────────────────

View File

@@ -414,7 +414,8 @@ async fn main() -> Result<(), std::io::Error> {
startup_agents.auto_assign_available_work(&root).await;
});
}
let addr = format!("127.0.0.1:{port}");
let host = std::env::var("STORKIT_HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
let addr = format!("{host}:{port}");
println!(
"\x1b[95;1m ____ _ _ ___ _ \n / ___|| |_ ___ _ __| | _|_ _| |_ \n \\___ \\| __/ _ \\| '__| |/ /| || __|\n ___) | || (_) | | | < | || |_ \n |____/ \\__\\___/|_| |_|\\_\\___|\\__|\n\x1b[0m"