This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch fix/CAMEL-23855
in repository https://gitbox.apache.org/repos/asf/camel.git

commit db0691c193983ab124178f6fc1df2c0d1f3fd58d
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Jun 29 18:36:09 2026 +0200

    CAMEL-23855: camel-jbang - AI panel space optimizations
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/dsl/jbang/core/commands/tui/AiPanel.java | 30 +++++++++++++++++-----
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
index e083564269f6..62cb48158807 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java
@@ -119,6 +119,14 @@ class AiPanel {
         return SPLIT_PERCENTS[splitIndex];
     }
 
+    private long lastResponseElapsed() {
+        if (thinking.get() || conversation.isEmpty()) {
+            return -1;
+        }
+        ConversationEntry last = conversation.get(conversation.size() - 1);
+        return "assistant".equals(last.role()) ? last.elapsedSeconds() : -1;
+    }
+
     void cycleHeight() {
         splitIndex = (splitIndex + 1) % SPLIT_PERCENTS.length;
     }
@@ -336,10 +344,21 @@ class AiPanel {
     }
 
     void render(Frame frame, Rect area) {
+        // At 25% show elapsed in the title bar to save space
+        long titleElapsed = lastResponseElapsed();
+        Line titleLine;
+        if (splitIndex == 0 && titleElapsed >= 0) {
+            titleLine = Line.from(
+                    Span.styled(" AI ", Style.EMPTY.bold()),
+                    Span.styled("(" + titleElapsed + "s) ", 
Style.EMPTY.dim()));
+        } else {
+            titleLine = Line.from(Span.styled(" AI ", Style.EMPTY.bold()));
+        }
+
         Block block = Block.builder()
                 .borders(Borders.ALL)
                 .borderType(BorderType.ROUNDED)
-                .title(Title.from(Line.from(Span.styled(" AI ", 
Style.EMPTY.bold()))))
+                .title(Title.from(titleLine))
                 .build();
         frame.renderWidget(block, area);
         Rect inner = block.inner(area);
@@ -347,14 +366,13 @@ class AiPanel {
             return;
         }
 
-        // Split inner area: conversation (fill) + separator (1 row) + input 
(1 row) + padding (1 row)
+        // Split inner area: conversation (fill) + separator (1 row) + input 
(1 row)
         List<Rect> parts = Layout.vertical()
-                .constraints(Constraint.fill(), Constraint.length(1), 
Constraint.length(1), Constraint.length(1))
+                .constraints(Constraint.fill(), Constraint.length(1), 
Constraint.length(1))
                 .split(inner);
         Rect conversationArea = parts.get(0);
         Rect separatorArea = parts.get(1);
         Rect inputArea = parts.get(2);
-        // parts.get(3) is empty padding row above the bottom border
 
         renderConversation(frame, conversationArea);
         // horizontal line separator
@@ -410,10 +428,10 @@ class AiPanel {
             }
         }
 
-        // Reserve 1 row for dimmed elapsed time when we have one to show
+        // Reserve 1 row for dimmed elapsed time (skip at 25% — shown in title 
bar instead)
         Rect mdArea = area;
         Rect elapsedArea = null;
-        if (lastElapsed >= 0 && area.height() > 2) {
+        if (lastElapsed >= 0 && splitIndex > 0 && area.height() > 2) {
             List<Rect> vParts = Layout.vertical()
                     .constraints(Constraint.fill(), Constraint.length(1))
                     .split(area);

Reply via email to