use std::sync as path_std_sync;
use std::sync::atomic as path_std_sync_atomic;
#[cfg(test)]
mod tests;
use tau_proto::{PromptMessageClass, PromptOriginator, UiCreateAgent};
static NEXT_CREATE_REQUEST_ID: path_std_sync::atomic::AtomicU64 =
path_std_sync_atomic::AtomicU64::new(1);
pub(crate) const DEFAULT_AGENT_ROLE: &str = "engineer";
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub(crate) enum PromptCommandHandling {
#[default]
Interpret,
LiteralEscape,
}
impl PromptCommandHandling {
fn is_literal_escape(self) -> bool {
matches!(self, Self::LiteralEscape)
}
}
#[derive(Clone, Debug, Default)]
pub(crate) struct CreateUserAgentPromptOptions {
pub(crate) model_override: Option<tau_proto::ModelId>,
pub(crate) effort_override: Option<tau_proto::ReasoningIntent>,
pub(crate) ephemeral: bool,
pub(crate) command_handling: PromptCommandHandling,
}
pub(crate) fn create_user_agent_prompt(
session_id: &tau_proto::SessionId,
role: impl Into<String>,
prompt: impl Into<String>,
options: CreateUserAgentPromptOptions,
) -> UiCreateAgent {
let next_id = || NEXT_CREATE_REQUEST_ID.fetch_add(1, path_std_sync_atomic::Ordering::Relaxed);
let process_id = std::process::id();
UiCreateAgent {
request_id: format!("ui-create-{process_id}-{}", next_id()),
parent_agent: None,
session_id: session_id.clone(),
role: role.into(),
model_override: options.model_override,
effort_override: options.effort_override,
metadata: Vec::new(),
initial_prompt: Some(prompt.into()),
literal: options.command_handling.is_literal_escape(),
message_class: PromptMessageClass::User,
originator: PromptOriginator::User,
ctx_id: Some(format!("ui-prompt-{process_id}-{}", next_id())),
ephemeral: options.ephemeral,
}
}