This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new e642b53badb2 CAMEL-26636: camel-jbang - TUI: the AI panel no longer
cuts the longest catalog answers (#29231)
e642b53badb2 is described below
commit e642b53badb25b7b2899204ddd89883c7ae85ff8
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Nov 5 18:54:19 2026 +0100
CAMEL-26636: camel-jbang - TUI: the AI panel no longer cuts the longest
catalog answers (#29231)
The AI panel cut every tool result at 16,000 characters. Since CAMEL-24961
a camel_catalog_doc answer can be 18,000 characters, and a long answer
names at its end the options and headers it leaves out, which the model
needs to ask for one of them. The panel cut that end off.
The panel now uses the longest catalog answer
(CatalogDocs.MAX_ANSWER_LENGTH,
made public) as its limit, so the two stay the same. A new test checks that
an answer of that length passes uncut. The AiPanel.java size cap is raised
to 3200.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java | 5 +++--
.../org/apache/camel/dsl/jbang/core/commands/tui/AiPanel.java | 8 ++++++--
.../dsl/jbang/core/commands/tui/AiPanelHistoryCompactionTest.java | 8 ++++++++
.../apache/camel/dsl/jbang/core/commands/tui/SourceSizeTest.java | 2 +-
4 files changed, 18 insertions(+), 5 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
index 6eaa63351c17..2849704bf3de 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocs.java
@@ -2033,9 +2033,10 @@ public final class CatalogDocs {
/**
* The longest answer, in characters: activemq listed 88 options in 38 K
characters, which a client rejected or
* spilled to a file instead of showing it to the model (CAMEL-25541).
Raised from 16000 for the body types
- * (CAMEL-24961), which the jms components have on four sides.
+ * (CAMEL-24961), which the jms components have on four sides. The AI
panel of the TUI hands tool results of this
+ * length to its model uncut.
*/
- static final int MAX_ANSWER_LENGTH = 18000;
+ public static final int MAX_ANSWER_LENGTH = 18000;
/** How much of the text of a page a cut answer keeps at least, before its
lists are cut. */
static final int MIN_DOC_KEPT = 8000;
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 63a47512a7e8..036db0262b07 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
@@ -66,6 +66,7 @@ import dev.tamboui.widgets.spinner.SpinnerStyle;
import org.apache.camel.dsl.jbang.core.commands.LlmClient;
import org.apache.camel.dsl.jbang.core.commands.ai.AnswerChecks;
import org.apache.camel.dsl.jbang.core.commands.ai.AppFeatures;
+import org.apache.camel.dsl.jbang.core.commands.ai.CatalogDocs;
import org.apache.camel.dsl.jbang.core.commands.ai.ToolConfirms;
import org.apache.camel.dsl.jbang.core.common.ExampleHelper;
import org.apache.camel.dsl.jbang.run.common.Printer;
@@ -91,9 +92,12 @@ class AiPanel {
static final int MAX_IDENTICAL_TOOL_CALLS = 3;
/**
* Longest tool result handed to the model. The AI log keeps the full
text; the model gets the head plus a note,
- * because a single log or table dump can otherwise be larger than the
whole system prompt.
+ * because a single log or table dump can otherwise be larger than the
whole system prompt. It is the longest answer
+ * of camel_catalog_doc, so no catalog answer is cut: a long one names at
its end the options and headers it leaves
+ * out, which the model needs to ask for one of them (16_000 cut that end
off, once the catalog answers grew to
+ * 18,000 characters).
*/
- static final int MAX_TOOL_RESULT_CHARS = 16_000;
+ static final int MAX_TOOL_RESULT_CHARS = CatalogDocs.MAX_ANSWER_LENGTH;
/**
* Tool results from turns before the previous one are shrunk to this many
characters once the turn is answered. The
* model's own answer already summarises them, and the whole history is
re-sent (and re-processed by a local model)
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanelHistoryCompactionTest.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanelHistoryCompactionTest.java
index 32d3bdce519c..b3a5f948dc9c 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanelHistoryCompactionTest.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/AiPanelHistoryCompactionTest.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.camel.dsl.jbang.core.commands.LlmClient;
+import org.apache.camel.dsl.jbang.core.commands.ai.CatalogDocs;
import org.apache.camel.util.json.JsonObject;
import org.junit.jupiter.api.Test;
@@ -146,6 +147,13 @@ class AiPanelHistoryCompactionTest {
assertTrue(truncated.contains("[truncated, 1234 more characters"));
}
+ @Test
+ void keepsTheLongestCatalogAnswerWhole() {
+ // the end of a long catalog answer names the options and headers it
leaves out (16_000 cut it off)
+ String longest = "z".repeat(CatalogDocs.MAX_ANSWER_LENGTH);
+ assertSame(longest, AiPanel.truncateToolResult(longest));
+ }
+
@Test
void compactsToolResultsOfOlderTurnsButKeepsThePreviousTurnIntact() {
List<LlmClient.Message> history = new ArrayList<>();
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceSizeTest.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceSizeTest.java
index fe089477f801..8c00f3036a6e 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceSizeTest.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceSizeTest.java
@@ -56,7 +56,7 @@ class SourceSizeTest {
/** The files and the methods (class.method) over the limits, and the most
lines each may have. */
private static final String OVER_THE_LIMITS = """
- AiPanel.java 3180
+ AiPanel.java 3200
AiPanel.runAgentLoop 159
AiUsageStats.render 166
CamelMonitor.java 2624