roboticus-api 0.11.3

HTTP routes, WebSocket, auth, rate limiting, and dashboard for the Roboticus agent runtime
Documentation
// ── Short-followup expansion ──────────────────────────────────────────────
//
// Detects brief user reactions (sarcasm, contradiction, quote-back) and
// prepends context from the previous assistant reply so the LLM can
// understand the reference.  Also drives `is_correction_turn` so that
// shortcut dispatch is skipped for corrections.

fn is_short_followup_for_previous_reply(user_content: &str) -> bool {
    let lower = user_content.trim().to_ascii_lowercase();
    if lower.len() > 80 {
        return false;
    }
    let markers = [
        "what's that from",
        "what is that from",
        "where is that from",
        "no, your quote",
        "your quote",
        "what quote",
        "source?",
    ];
    markers.iter().any(|m| lower.contains(m))
}

fn is_short_reactive_sarcasm(user_content: &str) -> bool {
    let lower = user_content.trim().to_ascii_lowercase();
    if lower.len() > 32 {
        return false;
    }
    let markers = [
        "wow",
        "great",
        "fantastic",
        "amazing",
        "incredible",
        "brilliant",
        "sure",
        "right",
    ];
    markers
        .iter()
        .any(|m| lower == *m || lower == format!("{m}.") || lower == format!("{m}..."))
}

fn is_short_contradiction_followup(user_content: &str) -> bool {
    let lower = user_content.trim().to_ascii_lowercase();
    if lower.len() > 48 {
        return false;
    }
    let markers = [
        "that's not true",
        "that is not true",
        "not true",
        "that's wrong",
        "that is wrong",
        "incorrect",
    ];
    markers
        .iter()
        .any(|m| lower == *m || lower == format!("{m}.") || lower.contains(m))
}

/// Expand a short user reaction by prepending the previous assistant reply.
///
/// Returns `(expanded_content, is_correction_turn)`.
pub(super) fn contextualize_short_followup(
    db: &roboticus_db::Database,
    session_id: &str,
    user_content: &str,
) -> (String, bool) {
    let is_sarcasm = is_short_reactive_sarcasm(user_content);
    let is_contradiction = is_short_contradiction_followup(user_content);
    let is_followup = is_short_followup_for_previous_reply(user_content);

    if !is_sarcasm && !is_contradiction && !is_followup {
        return (user_content.to_string(), false);
    }

    let Ok(history) = roboticus_db::sessions::list_messages(db, session_id, Some(20)) else {
        return (user_content.to_string(), is_sarcasm || is_contradiction);
    };
    let previous_assistant = history
        .iter()
        .rev()
        .find(|m| m.role == "assistant")
        .map(|m| m.content.trim())
        .filter(|s| !s.is_empty());
    let Some(previous_assistant) = previous_assistant else {
        return (user_content.to_string(), is_sarcasm || is_contradiction);
    };

    let correction = is_sarcasm || is_contradiction;

    if is_sarcasm {
        return (
            format!(
                "User likely reacted with sarcasm/frustration to your previous reply. Acknowledge the miss directly, do not treat it as praise, and correct course.\nPrevious assistant reply excerpt:\n\"{}\"\n\nUser reaction:\n{}",
                previous_assistant.chars().take(240).collect::<String>(),
                user_content
            ),
            correction,
        );
    }
    if is_contradiction {
        return (
            format!(
                "User directly disputed your previous reply as incorrect. Acknowledge the error and provide a corrected answer grounded in available tools/delegation.\nPrevious assistant reply excerpt:\n\"{}\"\n\nUser follow-up:\n{}",
                previous_assistant.chars().take(240).collect::<String>(),
                user_content
            ),
            correction,
        );
    }
    let quote = previous_assistant.chars().take(360).collect::<String>();
    (
        format!(
            "User follow-up references your immediately previous reply. Answer specifically what that prior reply/quote is from.\nPrevious assistant reply excerpt:\n\"{}\"\n\nUser question:\n{}",
            quote, user_content
        ),
        false,
    )
}