1+ use std:: collections:: VecDeque ;
12use std:: io:: Write ;
23
34use crossterm:: style:: Color ;
@@ -8,12 +9,13 @@ use crossterm::{
89use eyre:: {
910 Result ,
1011 WrapErr ,
12+ eyre,
1113} ;
1214use fig_os_shim:: Context ;
1315use serde:: Deserialize ;
1416
1517use super :: InvokeOutput ;
16- use crate :: cli:: chat:: conversation_state :: ConversationState ;
18+ use crate :: cli:: chat:: context :: ContextManager ;
1719use crate :: cli:: issue:: IssueCreator ;
1820
1921#[ derive( Debug , Clone , Deserialize ) ]
@@ -22,25 +24,36 @@ pub struct GhIssue {
2224 pub expected_behavior : Option < String > ,
2325 pub actual_behavior : Option < String > ,
2426 pub steps_to_reproduce : Option < String > ,
27+
28+ #[ serde( skip_deserializing) ]
29+ pub context : Option < GhIssueContext > ,
2530}
2631
27- pub struct GhIssueContext < ' a > {
28- pub conversation_state : & ' a ConversationState ,
29- pub failed_request_ids : & ' a Vec < String > ,
32+ #[ derive( Debug , Clone ) ]
33+ pub struct GhIssueContext {
34+ pub context_manager : Option < ContextManager > ,
35+ pub transcript : VecDeque < String > ,
36+ pub failed_request_ids : Vec < String > ,
3037}
3138
3239/// Max amount of user chat + assistant recent chat messages to include in the issue.
3340const MAX_TRANSCRIPT_LEN : usize = 10 ;
3441
3542impl GhIssue {
36- pub async fn invoke ( & self , _updates : impl Write , context : GhIssueContext < ' _ > ) -> Result < InvokeOutput > {
43+ pub async fn invoke ( & self , _updates : impl Write ) -> Result < InvokeOutput > {
44+ let Some ( context) = self . context . as_ref ( ) else {
45+ return Err ( eyre ! (
46+ "report_issue: Required tool context (GhIssueContext) not set by the program."
47+ ) ) ;
48+ } ;
49+
3750 // Prepare additional details from the chat session
38- let additional_environment = [ Self :: get_request_ids ( & context) , Self :: get_context ( & context) . await ] . join ( "\n \n " ) ;
51+ let additional_environment = [ Self :: get_request_ids ( context) , Self :: get_context ( context) . await ] . join ( "\n \n " ) ;
3952
4053 // Add chat history to the actual behavior text.
4154 let actual_behavior = self . actual_behavior . as_ref ( ) . map_or_else (
42- || Self :: get_transcript ( & context) ,
43- |behavior| format ! ( "{behavior}\n \n {}\n " , Self :: get_transcript( & context) ) ,
55+ || Self :: get_transcript ( context) ,
56+ |behavior| format ! ( "{behavior}\n \n {}\n " , Self :: get_transcript( context) ) ,
4457 ) ;
4558
4659 let _ = IssueCreator {
@@ -57,9 +70,13 @@ impl GhIssue {
5770 Ok ( Default :: default ( ) )
5871 }
5972
60- fn get_transcript ( context : & GhIssueContext < ' _ > ) -> String {
73+ pub fn set_context ( & mut self , context : GhIssueContext ) {
74+ self . context = Some ( context) ;
75+ }
76+
77+ fn get_transcript ( context : & GhIssueContext ) -> String {
6178 let mut transcript_str = String :: from ( "```\n [chat-transcript]\n " ) ;
62- let transcript: Vec < String > = context. conversation_state . transcript
79+ let transcript: Vec < String > = context. transcript
6380 . iter ( )
6481 . rev ( ) // To take last N items
6582 . scan ( 0 , |user_msg_count, line| {
@@ -89,7 +106,7 @@ impl GhIssue {
89106 transcript_str
90107 }
91108
92- fn get_request_ids ( context : & GhIssueContext < ' _ > ) -> String {
109+ fn get_request_ids ( context : & GhIssueContext ) -> String {
93110 format ! (
94111 "[chat-failed_request_ids]\n {}" ,
95112 if context. failed_request_ids. is_empty( ) {
@@ -100,9 +117,9 @@ impl GhIssue {
100117 )
101118 }
102119
103- async fn get_context ( context : & GhIssueContext < ' _ > ) -> String {
120+ async fn get_context ( context : & GhIssueContext ) -> String {
104121 let mut ctx_str = "[chat-context]\n " . to_string ( ) ;
105- let Some ( ctx_manager) = & context. conversation_state . context_manager else {
122+ let Some ( ctx_manager) = & context. context_manager else {
106123 ctx_str. push_str ( "No context available." ) ;
107124 return ctx_str;
108125 } ;
0 commit comments