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 c995d2a  chore: adjust phases for clarity
c995d2a is described below

commit c995d2ab3f1812704e26dbe9468d7de599c48865
Author: Robert Munteanu <[email protected]>
AuthorDate: Wed Oct 14 09:29:39 2026 +0100

    chore: adjust phases for clarity
---
 README.md                        | 12 +++++++-
 vars/slingOsgiBundleBuild.groovy | 61 +++++++++++++++++++++-------------------
 2 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/README.md b/README.md
index 3cd92b8..c7071bf 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,16 @@ When the branch job related to the modified `Jenkinsfile` is 
built, it will use
 
 `slingOsgiBundleBuild(llmaoOnly: true)` runs a separate Pi automation job, not 
the normal Maven matrix, SonarCloud analysis, deployment, or normal build 
notifications. Pi can run Maven as part of verifying its requested changes. 
Projects using `slingOsgiBundleBuild()` without this argument continue to build 
as before; they do not call LLMAO.
 
+The dedicated job's stages reflect the local agent workflow:
+
+1. **Checkout and Load Configuration** — check out the project and resolve 
module settings and library arguments.
+2. **Configure Job** — apply scheduling, retention, and concurrency settings, 
then read and validate the task input.
+3. **Build Pi Image** — build or reuse the cached Docker image, without 
binding credentials.
+4. **Prepare Pi Task** — write the prompts, model settings, runtime script, 
and bundled extensions outside the checkout.
+5. **Run Pi Task** — run the agent, including skill loading, LLMAO requests, 
project edits, verification, and diff output. An unsuccessful task fails this 
stage.
+6. **Publish Token Usage** — stop any remaining container and summarize and 
archive observed usage, also after build or task failures.
+7. **Clean Up** — remove generated runtime inputs and temporary reports, 
leaving project edits untouched.
+
 ### A separate scheduled job
 
 1. Create a **dedicated Pipeline job** for the project, for example 
`<project>-llmao`. This library does not create that job automatically.
@@ -199,7 +209,7 @@ In the Pi TUI, invoke the relevant skill explicitly when 
desired, for example `/
 
 ### Per-build token usage
 
-LLMAO builds that reach the submission stage publish a console summary, add 
the observed total to their build description (for example, `LLMAO: SUCCESS | 
18420 tokens`), and archive `llmao-usage.json`. Normal non-LLMAO builds are 
unaffected. No model prices or monetary cost estimates are configured.
+LLMAO builds that reach the image-build stage publish a console summary, add 
the observed total to their build description (for example, `LLMAO: SUCCESS | 
18420 tokens`), and archive `llmao-usage.json`. Normal non-LLMAO builds are 
unaffected. No model prices or monetary cost estimates are configured.
 
 A dedicated Pi extension collects gateway-reported usage across all model 
responses, including tool-calling turns and any usage reported on failed or 
retried turns. The report contains:
 
diff --git a/vars/slingOsgiBundleBuild.groovy b/vars/slingOsgiBundleBuild.groovy
index 90006ce..3bd83f4 100644
--- a/vars/slingOsgiBundleBuild.groovy
+++ b/vars/slingOsgiBundleBuild.groovy
@@ -155,7 +155,7 @@ def runLlmaoOnlyBuild(def globalConfig, Map params) {
 
     node(globalConfig.mainNodeLabel) {
         timeout(time: 30, unit: 'MINUTES') {
-            stage('Init') {
+            stage('Checkout and Load Configuration') {
                 checkout scm
                 if ( fileExists('.sling-module.json') ) {
                     def overrides = readJSON(file: '.sling-module.json', 
returnPojo: true).jenkins ?: [:]
@@ -173,6 +173,7 @@ def runLlmaoOnlyBuild(def globalConfig, Map params) {
                     error('llmaoMaxTokens must be a positive integer.')
             }
 
+            def contextData
             stage('Configure Job') {
                 def jobTriggers = []
                 // Standalone Pipeline jobs have no BRANCH_NAME. Feature 
branches
@@ -184,10 +185,6 @@ def runLlmaoOnlyBuild(def globalConfig, Map params) {
                     buildDiscarder(logRotator(numToKeepStr: '10')),
                     disableConcurrentBuilds()
                 ])
-            }
-
-            def contextData
-            stage('Prepare LLMAO Input') {
                 contextData = llmaoConfig.llmaoInputFile ?
                     readFile(file: llmaoConfig.llmaoInputFile, encoding: 
'UTF-8').trim() :
                     llmaoConfig.llmaoInput.trim()
@@ -213,13 +210,15 @@ def runLlmaoOnlyBuild(def globalConfig, Map params) {
                     "LLMAO_REPORT_DIR=${pwd()}/${reportDirectory}"
                 ]) {
                     try {
-                        stage('Submit to LLMAO') {
+                        stage('Build Pi Image') {
                             // Build before binding credentials or capturing 
stdout. Docker
                             // reuses the cached layers on subsequent runs on 
this executor.
                             dir('image') {
                                 writeFile file: 'Dockerfile', text: 
libraryResource('org/apache/sling/jenkins/llmao/Dockerfile')
                                 sh 'docker build --tag "$LLMAO_IMAGE" .'
                             }
+                        }
+                        stage('Prepare Pi Task') {
                             dir('inputs') {
                                 writeFile file: 'run-pi.sh', text: 
libraryResource('org/apache/sling/jenkins/llmao/run-pi.sh')
                                 writeFile file: 'tool-output-logger.mjs', 
text: libraryResource('org/apache/sling/jenkins/llmao/tool-output-logger.mjs')
@@ -252,44 +251,48 @@ def runLlmaoOnlyBuild(def globalConfig, Map params) {
                                     cacheWarming: 'off'
                                 ]
                             }
+                        }
+                        stage('Run Pi Task') {
                             withCredentials([string(credentialsId: 
'llmao-pat', variable: 'LLMAO_PAT')]) {
                                 updateStatus = sh(
                                     script: 
libraryResource('org/apache/sling/jenkins/llmao/run-docker.sh'),
                                     returnStatus: true
                                 )
                             }
+                            // Attribute update failures to the task, not a 
later response stage.
+                            if ( updateStatus == 0 ) {
+                                echo 'Pi completed the project update 
successfully.'
+                            } else {
+                                error("Pi could not complete the project 
update (exit code ${updateStatus}).")
+                            }
                         }
                     } finally {
                         try {
-                            // Stop writes before archiving, including on 
Jenkins cancellation.
-                            sh '''
-                                set +x
-                                docker rm --force "$LLMAO_CONTAINER" 
>/dev/null 2>&1 || true
-                            '''
-                            dir(reportDirectory) {
-                                publishLlmaoUsage(llmaoConfig.llmaoModel, 
updateStatus)
+                            stage('Publish Token Usage') {
+                                // Stop writes before archiving, including on 
Jenkins cancellation.
+                                sh '''
+                                    set +x
+                                    docker rm --force "$LLMAO_CONTAINER" 
>/dev/null 2>&1 || true
+                                '''
+                                dir(reportDirectory) {
+                                    publishLlmaoUsage(llmaoConfig.llmaoModel, 
updateStatus)
+                                }
                             }
                         } finally {
-                            sh '''
-                                set +x
-                                rm -f image/Dockerfile inputs/models.json 
inputs/settings.json \\
-                                  inputs/system-prompt.txt 
inputs/prompt_input.txt inputs/run-pi.sh \\
-                                  inputs/tool-output-logger.mjs 
inputs/usage-reporter.mjs
-                                rm -f "$LLMAO_REPORT_DIR/llmao-usage.json" 
"$LLMAO_REPORT_DIR/llmao-usage.json.tmp"
-                                rmdir "$LLMAO_REPORT_DIR" >/dev/null 2>&1 || 
true
-                            '''
+                            stage('Clean Up') {
+                                sh '''
+                                    set +x
+                                    rm -f image/Dockerfile inputs/models.json 
inputs/settings.json \\
+                                      inputs/system-prompt.txt 
inputs/prompt_input.txt inputs/run-pi.sh \\
+                                      inputs/tool-output-logger.mjs 
inputs/usage-reporter.mjs
+                                    rm -f "$LLMAO_REPORT_DIR/llmao-usage.json" 
"$LLMAO_REPORT_DIR/llmao-usage.json.tmp"
+                                    rmdir "$LLMAO_REPORT_DIR" >/dev/null 2>&1 
|| true
+                                '''
+                            }
                         }
                     }
                 }
             }
-
-            stage('Process LLMAO Response') {
-                if ( updateStatus == 0 ) {
-                    echo 'Pi completed the project update successfully.'
-                } else {
-                    error("Pi could not complete the project update (exit code 
${updateStatus}).")
-                }
-            }
         }
     }
 }

Reply via email to