33import com .google .gson .GsonBuilder ;
44import de .uka .ilkd .key .gui .MainWindow ;
55import de .uka .ilkd .key .gui .actions .KeyAction ;
6+ import de .uka .ilkd .key .gui .colors .ColorSettings ;
67import de .uka .ilkd .key .gui .extension .api .TabPanel ;
8+ import net .miginfocom .layout .CC ;
9+ import net .miginfocom .layout .LC ;
10+ import net .miginfocom .swing .MigLayout ;
711import org .jspecify .annotations .NonNull ;
812import org .slf4j .Logger ;
913import org .slf4j .LoggerFactory ;
1014
1115import javax .swing .*;
1216import java .awt .*;
1317import java .awt .event .*;
18+ import java .util .Arrays ;
1419import java .util .Collection ;
1520import java .util .List ;
1621import java .util .Map ;
2328 */
2429public class LlmPrompt extends JPanel implements TabPanel {
2530 private static final Logger LOGGER = LoggerFactory .getLogger (LlmPrompt .class );
31+ public static final ColorSettings .ColorProperty COLOR_BG_INPUT = ColorSettings .define (
32+ "llm.output.bg.input" ,
33+ "Background color in chat of LLM answers" , new Color (130 , 180 , 220 , 255 ));
34+
35+ public static final ColorSettings .ColorProperty COLOR_BG_ERROR
36+ = ColorSettings .define ("llm.output.bg.error" , "Background color in chat of LLM answers" , new Color (255 , 180 , 180 , 255 ));
37+
38+ private static final ColorSettings .ColorProperty COLOR_BG_ANSWER
39+ = ColorSettings .define ("llm.output.bg.answer" , "Background color in chat of LLM answers" , Color .LIGHT_GRAY );
40+
2641 private final JSplitPane splitPane = new JSplitPane (JSplitPane .VERTICAL_SPLIT );
2742
2843 private final JEditorPane txtInput = new JEditorPane ();
2944
30- private final Box pOutput = new Box ( BoxLayout . Y_AXIS );
45+ private final JPanel pOutput = new JPanel ( new MigLayout ( new LC (). fillX (). debug (). topToBottom (). wrapAfter ( 1 )) );
3146
3247 private final KeyAction actionSwitchOrientation = new SwitchOrientationAction ();
48+ private final SendPromptAction actionSendPrompt = new SendPromptAction ();
3349
3450 public LlmPrompt () {
3551 setLayout (new BorderLayout ());
3652 add (splitPane , BorderLayout .CENTER );
37- splitPane .add (new JScrollPane (pOutput ));
53+ final var comp = new JScrollPane (pOutput );
54+ comp .getVerticalScrollBar ().setUnitIncrement (16 );
55+ splitPane .add (comp );
3856 splitPane .add (new JScrollPane (txtInput ));
3957
4058 handle (new Exception ("Test Exception" ));
@@ -47,42 +65,17 @@ public LlmPrompt() {
4765 @ Override
4866 public void keyTyped (KeyEvent e ) {
4967 if (e .getKeyChar () == KeyEvent .VK_ENTER && (e .getModifiersEx () & InputEvent .CTRL_DOWN_MASK ) > 0 ) {
50- var proof = MainWindow .getInstance ().getMediator ().getSelectedProof ();
51- var node = MainWindow .getInstance ().getMediator ().getSelectedNode ();
52-
53- LlmSession session = LlmUtils .getSession (proof );
54- var txt = txtInput .getText ();
55- LlmClient client = new LlmClient (session , new LlmContext (), txt );
56- addInput (txt );
57- txtInput .setText ("" );
58-
59- var sw = new SwingWorker <Map <String , Object >, Void >() {
60- @ Override
61- protected Map <String , Object > doInBackground () throws Exception {
62- return client .call ();
63- }
64-
65- @ Override
66- protected void done () {
67- try {
68- handle (resultNow ());
69- } catch (IllegalStateException ex ) {
70- LOGGER .error ("Exceptional case" , exceptionNow ());
71- handle (exceptionNow ());
72- }
73- }
74- };
75- ForkJoinPool .commonPool ().submit (sw );
68+ actionSendPrompt .run ();
7669 }
7770 }
7871 });
7972 }
8073
8174 public static class OutputBox <T > extends JPanel {
82- private final T userData ;
83- private final JEditorPane output = new JEditorPane ();
84- private final JPanel buttons = new JPanel ();
85- private final JPopupMenu menu = new JPopupMenu ();
75+ protected final T userData ;
76+ protected final JEditorPane output = new JEditorPane ();
77+ protected final JPanel buttons = new JPanel ();
78+ protected final JPopupMenu menu = new JPopupMenu ();
8679
8780 public OutputBox (T userData ) {
8881 this (userData , userData .toString ());
@@ -119,28 +112,32 @@ public void setBackground(Color bg) {
119112 }
120113
121114 private OutputBox <String > addInput (String text ) {
122- var o = addBox (text , new RepromptAction (text ));
123- o .setBackground (new Color ( 130 , 180 , 220 , 255 ));
115+ var o = addBox (text , new RepromptAction (text ));
116+ o .setBackground (COLOR_BG_INPUT . get ( ));
124117 return o ;
125118 }
126119
127- private <T > OutputBox <T > addBox (T data , Action ... action ) {
120+ private <T > OutputBox <T > addBox (T data , Action ... actions ) {
128121 OutputBox <T > box = new OutputBox <>(data );
129- pOutput .add (box );
122+ for (Action it : actions ) {
123+ box .menu .add (it );
124+ }
125+ pOutput .add (box , new CC ().growX ());
130126 return box ;
131127 }
132128
133129 private void handle (Map <String , Object > jsonResponse ) {
134130 LOGGER .info ("LLM prompt {}" , jsonResponse );
135131 var o = new OutputBox <>(jsonResponse ,
136132 ((Map <String , Object >) ((Map <String , Object >) ((List <?>) jsonResponse .get ("choices" )).get (0 )).get ("message" )).get ("content" ).toString ());
137- pOutput .add (o );
133+ pOutput .add (o , new CC ().growX ());
134+ o .setBackground (COLOR_BG_ANSWER .get ());
138135 }
139136
140137 private void handle (Throwable e ) {
141138 LOGGER .error ("Error during LLM prompt" , e );
142139 var box = addBox (e );
143- box .setBackground (new Color ( 255 , 180 , 180 , 255 ));
140+ box .setBackground (COLOR_BG_ERROR . get ( ));
144141 }
145142
146143 @ Override
@@ -181,9 +178,42 @@ public void actionPerformed(ActionEvent e) {
181178 }
182179
183180 class SendPromptAction extends KeyAction {
181+ public SendPromptAction () {
182+ setName ("Send Prompt" );
183+ }
184+
184185 @ Override
185186 public void actionPerformed (ActionEvent e ) {
186- String prompt = txtInput .getText ();
187+ run ();
188+ }
189+
190+ public void run () {
191+ var proof = MainWindow .getInstance ().getMediator ().getSelectedProof ();
192+ var node = MainWindow .getInstance ().getMediator ().getSelectedNode ();
193+
194+ LlmSession session = LlmUtils .getSession (proof );
195+ var txt = txtInput .getText ();
196+ LlmClient client = new LlmClient (session , new LlmContext (), txt );
197+ addInput (txt );
198+ txtInput .setText ("" );
199+
200+ var sw = new SwingWorker <Map <String , Object >, Void >() {
201+ @ Override
202+ protected Map <String , Object > doInBackground () throws Exception {
203+ return client .call ();
204+ }
205+
206+ @ Override
207+ protected void done () {
208+ try {
209+ handle (resultNow ());
210+ } catch (IllegalStateException ex ) {
211+ LOGGER .error ("Exceptional case" , exceptionNow ());
212+ handle (exceptionNow ());
213+ }
214+ }
215+ };
216+ ForkJoinPool .commonPool ().submit (sw );
187217 }
188218 }
189219
0 commit comments