Files
huskies/server/src/chat/transport/whatsapp/commands/llm.rs
T

58 lines
1.9 KiB
Rust

//! WhatsApp LLM message handler — runs an LLM turn for a non-command message.
use std::sync::Arc;
use super::super::WhatsAppWebhookContext;
use super::super::format::{chunk_for_whatsapp, markdown_to_whatsapp};
use super::super::history::save_whatsapp_history;
/// [`crate::chat::llm_turn::TransportFormat`] implementation for WhatsApp:
/// messages are markdown-converted then split to fit the platform's size
/// limit, and LLM errors are checked for an OAuth login link.
#[derive(Clone, Copy)]
struct WhatsAppFormat;
impl crate::chat::llm_turn::TransportFormat for WhatsAppFormat {
fn format_and_chunk(&self, markdown: &str) -> Vec<String> {
chunk_for_whatsapp(&markdown_to_whatsapp(markdown))
}
fn log_prefix(&self) -> &'static str {
"[whatsapp]"
}
fn format_error(&self, err: &str) -> String {
if let Some(url) = crate::llm::oauth::extract_login_url_from_error(err) {
format!("Authentication required. Log in to Claude here: {url}")
} else {
format!("Error processing your request: {err}")
}
}
}
/// Forward a message to Claude Code and send the response back via WhatsApp.
pub(super) async fn handle_llm_message(
ctx: &WhatsAppWebhookContext,
sender: &str,
user_message: &str,
) {
use crate::chat::llm_turn::{LlmTurnContext, run_llm_turn};
run_llm_turn(
LlmTurnContext {
transport: Arc::clone(&ctx.transport),
key: sender,
user: sender,
services: &ctx.services,
history: &ctx.history,
history_size: ctx.history_size,
save_history: save_whatsapp_history,
},
WhatsAppFormat,
user_message,
)
.await;
}
// ── Tests ───────────────────────────────────────────────────────────────