use vtcode_core::llm::provider as uni;
use vtcode_core::utils::ansi::{AnsiRenderer, MessageStyle};
pub(crate) const PLANNING_SYNTHESIS_TRUNCATED_CONDENSE_DIRECTIVE: &str = "Your previous `<proposed_plan>` was cut off at the token limit. Re-emit ONE compact `<proposed_plan>` spec that fits within the limit: keep each step to a single line (`Action -> files/symbols -> verify:`), drop prose, and prefer file:symbol references. Do not repeat the truncated draft.";
const MAX_PLAN_SYNTHESIS_CONDENSE_ATTEMPTS: u8 = 1;
pub(crate) fn plan_synthesis_was_truncated(response: &uni::LLMResponse) -> bool {
matches!(response.finish_reason, uni::FinishReason::Length)
&& response.tool_calls.as_ref().is_none_or(|calls| calls.is_empty())
&& response
.content
.as_deref()
.is_some_and(|text| text.contains("<proposed_plan") && !text.contains("</proposed_plan>"))
}
pub(crate) fn maybe_condense_truncated_plan(
working_history: &mut Vec<uni::Message>,
renderer: &mut AnsiRenderer,
planning_active: bool,
tool_free_recovery: bool,
attempts: &mut u8,
response: &uni::LLMResponse,
) -> bool {
if tool_free_recovery
|| !planning_active
|| !plan_synthesis_was_truncated(response)
|| *attempts >= MAX_PLAN_SYNTHESIS_CONDENSE_ATTEMPTS
{
return false;
}
*attempts += 1;
working_history.push(uni::Message::system(PLANNING_SYNTHESIS_TRUNCATED_CONDENSE_DIRECTIVE.to_string()));
let _ = renderer.line(MessageStyle::Info, "Plan was truncated at the token limit; requesting a more compact spec.");
true
}