Skip to main content

codetether_agent/session/context/
complete.rs

1//! Complete provider calls with derived-context retry.
2
3use std::sync::Arc;
4
5use anyhow::Result;
6
7use crate::provider::{CompletionResponse, Provider, ToolDefinition};
8use crate::session::Session;
9use crate::session::helper::prompt_too_long;
10
11use super::options::RequestOptions;
12use super::request::build_request_with_context;
13
14/// Complete a derived-context request, retrying with forced compaction.
15pub async fn complete_with_context(
16    provider: Arc<dyn Provider>,
17    session: &Session,
18    model: &str,
19    system_prompt: &str,
20    tools: &[ToolDefinition],
21    mut opts: RequestOptions,
22) -> Result<CompletionResponse> {
23    let mut attempt = 1usize;
24    loop {
25        let request = build_request_with_context(
26            Arc::clone(&provider),
27            session,
28            model,
29            system_prompt,
30            tools,
31            opts,
32        )
33        .await?;
34        match provider.complete(request).await {
35            Ok(response) => return Ok(response),
36            Err(error) => {
37                let Some(keep_last) = prompt_too_long::keep_last(&error, attempt) else {
38                    return Err(error);
39                };
40                opts = RequestOptions {
41                    force_keep_last: Some(keep_last),
42                    ..opts
43                };
44                attempt += 1;
45            }
46        }
47    }
48}