This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch feat/llmao
in repository https://gitbox.apache.org/repos/asf/sling-tooling-jenkins.git
The following commit(s) were added to refs/heads/feat/llmao by this push:
new 4247dab feat: more pi output for understanding/troubleshooting
4247dab is described below
commit 4247dabe88dbc4a8f31655c2ba6ef75201243d8b
Author: Robert Munteanu <[email protected]>
AuthorDate: Wed Oct 14 09:23:53 2026 +0100
feat: more pi output for understanding/troubleshooting
---
README.md | 4 +--
resources/org/apache/sling/jenkins/llmao/run-pi.sh | 3 +-
.../sling/jenkins/llmao/tool-output-logger.mjs | 37 +++++++++++++++++++---
3 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index cb4bf8a..3cd92b8 100644
--- a/README.md
+++ b/README.md
@@ -85,7 +85,7 @@ Provide either an input string or an input file; the library
has no default task
The library runs [Pi](https://pi.dev) in Docker, configured for LLMAO's
OpenAI-compatible endpoint at `https://llm.apache.org/v1`, with the selected
model and temperature `0.0`. Pi can read, search, edit, and write project files
and run shell commands. Automatic extensions, MCP, automatic project
instructions, stored sessions, and compaction remain disabled.
-A bundled tool-output logger is explicitly loaded. It writes shell commands
(up to 2,000 characters), shell-result tails (up to 6,000 characters), and
errors from other tools to stderr in the Jenkins console. It redacts the
`LLMAO_PAT` value before truncation and does not log successful file reads,
prompts, or reasoning. It does not alter tool results or the final
SUCCESS/FAILURE response on stdout.
+A bundled output logger is explicitly loaded. It writes Pi's assistant text,
model-response stop reasons/errors, agent/request progress, tool starts and
completion status, and tool-result tails to stderr in the Jenkins console.
Tool-call summaries include shell commands, paths, and search patterns (up to
2,000 characters), but not file contents supplied to edit/write tools.
Assistant text and tool results are limited to their last 6,000 characters;
successful file/skill-read contents, pr [...]
Pi retries transient provider/network errors, including HTTP 429 rate limits,
up to 10 times per failed model turn at one-minute intervals. Retries stay in
the same Pi session, preserving tool history and edits; provider-level retries
remain disabled. This polls for quota recovery rather than parsing LLMAO's
custom reset timestamp, and the existing job/process timeouts still apply.
@@ -241,4 +241,4 @@ docker build --tag sling-llmao-pi:1.1.0-jdk21-v3
resources/org/apache/sling/jenk
python3 tests/pi-docker.py --integration
```
-The integration test exercises skill discovery/loading, real
read/edit/write/find/shell tool calls, Java 21 with both Maven commands and the
absence of older JDKs/wrappers, Maven batch-mode settings, environment-token
authentication, model selection, tracked/new-file diffs, SUCCESS/FAILURE
mapping, malformed/empty answers, API errors, multi-turn token/cache totals,
retries, missing/zero usage, cancellation, and container removal. It uses only
disposable fixture projects and does not call [...]
+The integration test exercises skill discovery/loading, real
read/edit/write/find/shell tool calls, assistant/progress/tool console output
with private read contents, Java 21 with both Maven commands and the absence of
older JDKs/wrappers, Maven batch-mode settings, environment-token
authentication, model selection, tracked/new-file diffs, SUCCESS/FAILURE
mapping, malformed/empty answers, API errors, multi-turn token/cache totals,
retries, missing/zero usage, cancellation, and container [...]
diff --git a/resources/org/apache/sling/jenkins/llmao/run-pi.sh
b/resources/org/apache/sling/jenkins/llmao/run-pi.sh
index ee94cf6..db8a1f4 100644
--- a/resources/org/apache/sling/jenkins/llmao/run-pi.sh
+++ b/resources/org/apache/sling/jenkins/llmao/run-pi.sh
@@ -40,7 +40,8 @@ git -C "$HOME/sling-whiteboard" sparse-checkout set skills >&2
printf 'Sling skills revision: ' >&2
git -C "$HOME/sling-whiteboard" rev-parse HEAD >&2
-# Print mode emits only the final assistant text to stdout; errors use stderr.
+# Print mode keeps the final assistant text on stdout for the result check.
+# The output logger sends assistant/progress/tool diagnostics to stderr.
exec timeout --kill-after=5s 1500s pi \
--provider llmao --model "$LLMAO_MODEL" \
--print --tools read,bash,edit,write,grep,find,ls --no-session \
diff --git a/resources/org/apache/sling/jenkins/llmao/tool-output-logger.mjs
b/resources/org/apache/sling/jenkins/llmao/tool-output-logger.mjs
index 0722eb2..743411f 100644
--- a/resources/org/apache/sling/jenkins/llmao/tool-output-logger.mjs
+++ b/resources/org/apache/sling/jenkins/llmao/tool-output-logger.mjs
@@ -18,24 +18,51 @@
*/
export default function toolOutputLogger(pi) {
- function log(value, limit = 6000) {
+ function log(value, limit = 6000, prefix = 'Pi tool') {
let text = String(value ?? '');
const secret = process.env.LLMAO_PAT;
if (secret) text = text.split(secret).join('[REDACTED]');
text = text.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
if (text.length > limit) text = `[...truncated; last ${limit}
characters...]\n${text.slice(-limit)}`;
- process.stderr.write(`[Pi tool] ${text}\n`);
+ process.stderr.write(`[${prefix}] ${text}\n`);
}
+ function textBlocks(content) {
+ return (Array.isArray(content) ? content : []).filter(block =>
block?.type === 'text').map(block => block.text).join('\n');
+ }
+
+ function progress(value) {
+ log(value, 6000, 'Pi');
+ }
+
+ pi.on('agent_start', () => { progress('Agent started'); });
+ pi.on('before_provider_request', () => { progress('Requesting the next
model response'); });
+
+ pi.on('message_end', event => {
+ const message = event.message;
+ if (message?.role !== 'assistant') return;
+ const output = textBlocks(message.content);
+ if (output) progress(`Assistant output:\n${output}`);
+ progress(`Model response ended: ${message.stopReason ?? 'unknown'}`);
+ if (message.errorMessage) progress(message.errorMessage);
+ if (message.stopReason === 'length') progress('Model output was
truncated. Increase llmaoMaxTokens only if the gateway quota allows it.');
+ // Observe only: do not change the assistant message or print
reasoning.
+ });
+
+ pi.on('agent_settled', event => { progress(event.aborted ? 'Agent aborted'
: 'Agent settled'); });
+
pi.on('tool_call', event => {
if (event.toolName === 'bash') log(`bash
command:\n${event.input?.command ?? ''}`, 2000);
+ else log(`${event.toolName}: starting${event.input?.path ? `
(${event.input.path})` : ''}${event.input?.pattern ? `
pattern=${event.input.pattern}` : ''}`, 2000);
});
pi.on('tool_result', event => {
- if (event.toolName !== 'bash' && !event.isError) return;
log(`${event.toolName}: ${event.isError ? 'ERROR' :
'OK'}${event.input?.path ? ` (${event.input.path})` : ''}`);
- const output = (event.content ?? []).filter(block => block.type ===
'text').map(block => block.text).join('\n');
- if (output) log(output);
+ // Keep successful file/skill reads private, but show other tool
output.
+ if (event.toolName !== 'read' || event.isError) {
+ const output = textBlocks(event.content);
+ if (output) log(output);
+ }
// Return nothing: logging must not change the result seen by the
model.
});
}