use std::future::Future;
use std::path::PathBuf;
use std::pin::Pin;
use std::sync::Arc;
use tokio::sync::mpsc;
use crate::app_server::AppServerError;
use crate::channel::{AgentRequestKind, LiveTranscript};
use crate::model::agent::ReasoningLevel;
use crate::model::turn_prompt::TurnPrompt;
pub type AppServerFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
pub(crate) type BorrowedAppServerFuture<'scope, T> =
Pin<Box<dyn Future<Output = T> + Send + 'scope>>;
#[derive(Clone, Debug, PartialEq)]
pub enum AppServerStreamEvent {
AssistantMessage {
message: String,
phase: Option<String>,
is_delta: bool,
},
ProgressUpdate(String),
}
#[derive(Clone)]
pub struct AppServerTurnRequest {
pub folder: PathBuf,
pub live_transcript: Option<Arc<dyn LiveTranscript>>,
pub main_checkout_root: Option<PathBuf>,
pub model: String,
pub prompt: TurnPrompt,
pub request_kind: AgentRequestKind,
pub replay_transcript: Option<String>,
pub provider_conversation_id: Option<String>,
pub persisted_instruction_conversation_id: Option<String>,
pub reasoning_level: ReasoningLevel,
pub session_id: String,
}
#[derive(Debug)]
pub struct AppServerTurnResponse {
pub assistant_message: String,
pub context_reset: bool,
pub input_tokens: u64,
pub output_tokens: u64,
pub pid: Option<u32>,
pub provider_conversation_id: Option<String>,
}
#[cfg_attr(any(test, feature = "test-utils"), mockall::automock)]
pub trait AppServerClient: Send + Sync {
fn run_turn(
&self,
request: AppServerTurnRequest,
stream_tx: mpsc::UnboundedSender<AppServerStreamEvent>,
) -> AppServerFuture<Result<AppServerTurnResponse, AppServerError>>;
fn shutdown_session(&self, session_id: String) -> AppServerFuture<()>;
}