Lyra Agent hinzugefügt, Multi-Agent Routing, BaseAgent refactoring
This commit is contained in:
@@ -186,16 +186,26 @@ async fn process(state: Arc<AppState>, payload: SynologyIncoming, agent: AgentCh
|
||||
// ─── HTTP Sender ──────────────────────────────────────────────────────────────
|
||||
//
|
||||
// Sendet eine Nachricht an einen Synology Chat User.
|
||||
// Synology erwartet Form-encoded payload mit JSON — kein reines JSON.
|
||||
// user_id wird dynamisch angehängt — Basis-URL bleibt sauber in config.toml.
|
||||
// Lange Nachrichten werden automatisch in Chunks aufgeteilt.
|
||||
// Synology erlaubt max. ~2000 Zeichen pro Nachricht.
|
||||
|
||||
const MAX_CHUNK_SIZE: usize = 1800; // Puffer unter dem Limit
|
||||
|
||||
async fn send(client: &Client, base_url: &str, user_id: u64, text: &str) {
|
||||
let chunks = split_message(text);
|
||||
|
||||
for chunk in chunks {
|
||||
send_chunk(client, base_url, user_id, &chunk).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Sendet einen einzelnen Chunk.
|
||||
async fn send_chunk(client: &Client, base_url: &str, user_id: u64, text: &str) {
|
||||
let body = SynologyOutgoing {
|
||||
text: text.to_string(),
|
||||
user_ids: vec![user_id],
|
||||
};
|
||||
|
||||
// JSON serialisieren und als Form-Parameter verpacken
|
||||
let payload = serde_json::to_string(&body).unwrap_or_default();
|
||||
|
||||
match client
|
||||
@@ -206,9 +216,38 @@ async fn send(client: &Client, base_url: &str, user_id: u64, text: &str) {
|
||||
{
|
||||
Ok(r) if r.status().is_success() => {
|
||||
let response_body = r.text().await.unwrap_or_default();
|
||||
info!("Nachricht gesendet an user_id={} body={}", user_id, response_body);
|
||||
info!("Chunk gesendet an user_id={} body={}", user_id, response_body);
|
||||
}
|
||||
Ok(r) => error!(status = %r.status(), "Synology hat abgelehnt"),
|
||||
Err(e) => error!(error = %e, "Senden fehlgeschlagen"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Teilt einen Text in Chunks auf die Synology verarbeiten kann.
|
||||
/// Schneidet an Zeilenumbrüchen oder Satzenden — nie mitten im Wort.
|
||||
fn split_message(text: &str) -> Vec<String> {
|
||||
if text.len() <= MAX_CHUNK_SIZE {
|
||||
return vec![text.to_string()];
|
||||
}
|
||||
|
||||
let mut chunks = Vec::new();
|
||||
let mut remaining = text;
|
||||
|
||||
while remaining.len() > MAX_CHUNK_SIZE {
|
||||
// Schnittpunkt suchen — bevorzugt Zeilenumbruch, dann Leerzeichen
|
||||
let cut = remaining[..MAX_CHUNK_SIZE]
|
||||
.rfind('\n')
|
||||
.or_else(|| remaining[..MAX_CHUNK_SIZE].rfind(". "))
|
||||
.or_else(|| remaining[..MAX_CHUNK_SIZE].rfind(' '))
|
||||
.unwrap_or(MAX_CHUNK_SIZE);
|
||||
|
||||
chunks.push(remaining[..cut].trim().to_string());
|
||||
remaining = remaining[cut..].trim_start();
|
||||
}
|
||||
|
||||
if !remaining.is_empty() {
|
||||
chunks.push(remaining.to_string());
|
||||
}
|
||||
|
||||
chunks
|
||||
}
|
||||
Reference in New Issue
Block a user