huskies: merge 927

This commit is contained in:
dave
2026-05-12 17:49:44 +00:00
parent b8945654bf
commit 03a99b3cf1
33 changed files with 119 additions and 25 deletions
+3 -3
View File
@@ -3,7 +3,7 @@
use async_trait::async_trait;
use serde::Deserialize;
use crate::chat::{ChatTransport, MessageId};
use crate::chat::{ChatTransport, MessageId, util::truncate_at_char_boundary};
use crate::slog;
// ── Discord API base URL (overridable for tests) ──────────────────────
@@ -71,7 +71,7 @@ impl ChatTransport for DiscordTransport {
// Discord messages have a 2000-char limit. Truncate if needed.
let content = if plain.len() > 2000 {
format!("{}", &plain[..1999])
format!("{}", truncate_at_char_boundary(plain, 1999))
} else {
plain.to_string()
};
@@ -118,7 +118,7 @@ impl ChatTransport for DiscordTransport {
);
let content = if plain.len() > 2000 {
format!("{}", &plain[..1999])
format!("{}", truncate_at_char_boundary(plain, 1999))
} else {
plain.to_string()
};
@@ -37,6 +37,7 @@ pub fn mentions_bot(body: &str, formatted_body: Option<&str>, bot_user_id: &Owne
}
/// Returns `true` if `haystack` contains `needle` at a word boundary.
#[allow(clippy::string_slice)] // all indices from find() or abs+needle.len() → always char boundaries
pub(super) fn contains_word(haystack: &str, needle: &str) -> bool {
let mut start = 0;
while let Some(rel) = haystack[start..].find(needle) {
@@ -87,6 +88,7 @@ pub(super) async fn is_reply_to_bot(
///
/// Used in ambient mode to suppress responses when a message is clearly
/// directed at a different participant (e.g. another bot in the same room).
#[allow(clippy::string_slice)] // word_end and colon_pos from find() → always char boundaries
pub fn is_addressed_to_other(body: &str, bot_user_id: &OwnedUserId, bot_name: &str) -> bool {
let trimmed = body.trim_start();
let lower = trimmed.to_lowercase();
+1
View File
@@ -101,6 +101,7 @@ fn parse_duration(s: &str) -> Option<u64> {
///
/// Returns a short string like `"load average: 1.23, 0.98, 0.75"` on success,
/// or `"load: unknown"` on failure.
#[allow(clippy::string_slice)] // idx comes from output.find("load average") → always a char boundary
fn get_load_average() -> String {
let output = std::process::Command::new("uptime")
.output()
+3 -2
View File
@@ -1,4 +1,5 @@
//! WhatsApp message formatting — Markdown-to-WhatsApp conversion and message chunking.
use crate::chat::util::truncate_at_char_boundary;
use regex::Regex;
use std::sync::LazyLock;
@@ -24,13 +25,13 @@ pub fn chunk_for_whatsapp(text: &str) -> Vec<String> {
}
// Find the best split point within the limit.
let window = &remaining[..WHATSAPP_MAX_MESSAGE_LEN];
let window = truncate_at_char_boundary(remaining, WHATSAPP_MAX_MESSAGE_LEN);
// Prefer paragraph boundary.
let split_pos = window
.rfind("\n\n")
.or_else(|| window.rfind('\n'))
.unwrap_or(WHATSAPP_MAX_MESSAGE_LEN);
.unwrap_or(window.len());
let (chunk, rest) = remaining.split_at(split_pos);
let chunk = chunk.trim();