@@ -245,20 +245,32 @@ struct FileAttachment {
245245impl RunCli {
246246 /// Run the command.
247247 pub async fn run ( self ) -> Result < ( ) > {
248- // Validate temperature if provided
248+ // Validate temperature if provided using epsilon-based comparison
249+ // to handle floating-point boundary issues (#2179)
250+ const EPSILON : f32 = 1e-6 ;
249251 if let Some ( temp) = self . temperature {
250- if ! ( 0.0 ..= 2.0 ) . contains ( & temp ) {
252+ if temp < - EPSILON || temp > 2.0 + EPSILON {
251253 bail ! ( "Temperature must be between 0.0 and 2.0, got {temp}" ) ;
252254 }
253255 }
254256
255- // Validate top_p if provided
257+ // Validate top_p if provided using epsilon-based comparison
256258 if let Some ( top_p) = self . top_p {
257- if ! ( 0.0 ..= 1.0 ) . contains ( & top_p ) {
259+ if top_p < - EPSILON || top_p > 1.0 + EPSILON {
258260 bail ! ( "top-p must be between 0.0 and 1.0, got {top_p}" ) ;
259261 }
260262 }
261263
264+ // Warn if both temperature and top-p are specified (#2175)
265+ if self . temperature . is_some ( ) && self . top_p . is_some ( ) {
266+ eprintln ! (
267+ "{}Warning:{} Using both --temperature and --top-p together may produce unpredictable results. \
268+ Most LLM providers recommend using only one sampling parameter at a time.",
269+ TermColor :: Yellow . ansi_code( ) ,
270+ TermColor :: Default . ansi_code( )
271+ ) ;
272+ }
273+
262274 // Validate command is not empty if provided
263275 if let Some ( ref cmd) = self . command {
264276 if cmd. trim ( ) . is_empty ( ) {
@@ -612,6 +624,7 @@ impl RunCli {
612624 let mut streaming_started = false ;
613625 let mut error_occurred = false ;
614626 let mut task_completed = false ;
627+ let mut response_truncated = false ; // Track if response was truncated (#2174)
615628
616629 // Set up timeout if specified
617630 let timeout_duration = if self . timeout > 0 {
@@ -651,6 +664,19 @@ impl RunCli {
651664 match & event. msg {
652665 EventMsg :: AgentMessage ( msg) => {
653666 final_message = msg. message . clone ( ) ;
667+ // Check if response was truncated due to token limit (#2174)
668+ if let Some ( ref reason) = msg. finish_reason {
669+ if reason == "length" {
670+ response_truncated = true ;
671+ if !is_json {
672+ eprintln ! (
673+ "{}Warning:{} Response was truncated due to max token limit." ,
674+ TermColor :: Yellow . ansi_code( ) ,
675+ TermColor :: Default . ansi_code( )
676+ ) ;
677+ }
678+ }
679+ }
654680 }
655681 EventMsg :: AgentMessageDelta ( delta) => {
656682 // Handle streaming output
@@ -770,6 +796,8 @@ impl RunCli {
770796 "message" : final_message,
771797 "events" : event_count,
772798 "success" : !error_occurred,
799+ "truncated" : response_truncated,
800+ "finish_reason" : if response_truncated { "length" } else if error_occurred { "error" } else { "stop" } ,
773801 } ) ;
774802 println ! ( "{}" , serde_json:: to_string_pretty( & result) ?) ;
775803 }
@@ -812,9 +840,14 @@ impl RunCli {
812840 drop ( handle) ;
813841 let _ = session_task. await ;
814842
843+ // Exit with appropriate code (#2174)
815844 if error_occurred {
816845 std:: process:: exit ( 1 ) ;
817846 }
847+ if response_truncated {
848+ // Exit with code 2 to indicate truncation (distinct from error code 1)
849+ std:: process:: exit ( 2 ) ;
850+ }
818851
819852 Ok ( ( ) )
820853 }
0 commit comments