fix(i18n): retain Codex error tails in logs (#93687)

Summary:
- This PR changes the docs i18n Codex command-output preview to keep a short head plus retained tail, and adds Go unit coverage for stdout and stderr tails.
- PR surface: Other +20. Total +20 across 2 files.
- Reproducibility: yes. Source inspection of current main and `v2026.6.6` shows long output is truncated to the prefix only, and the PR's focused tests model the stdout/stderr tail cases that lose final API details.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head b510b598c6.
- Required merge gates passed before the squash merge.

Prepared head SHA: b510b598c6
Review: https://github.com/openclaw/openclaw/pull/93687#issuecomment-4720840859

Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Mason Huang <8814856+hxy91819@users.noreply.github.com>
Approved-by: hxy91819
This commit is contained in:
clawsweeper[bot]
2026-06-16 16:14:12 +00:00
committed by GitHub
parent 3630ce6cbb
commit 5ce413a2c7
2 changed files with 25 additions and 5 deletions

View File

@@ -315,11 +315,16 @@ func previewCommandOutput(stdout, stderr string) string {
return "no output"
}
combined = strings.Join(strings.Fields(combined), " ")
const limit = 500
const (
limit = 1200
headLength = 300
tailLength = 800
)
if len(combined) <= limit {
return combined
}
return combined[:limit] + "..."
// Codex prints API failures after its header and prompt, so the tail carries the actionable error.
return combined[:headLength] + " ... [truncated] ... " + combined[len(combined)-tailLength:]
}
func sleepWithContext(ctx context.Context, delay time.Duration) error {

View File

@@ -336,7 +336,7 @@ sleep 10
}
func TestPreviewCommandOutputFlattensAndTruncates(t *testing.T) {
input := "line one\n\nline two\tline three " + strings.Repeat("x", 600)
input := "line one\n\nline two\tline three " + strings.Repeat("x", 1200) + " final api error 429"
preview := previewCommandOutput(input, "")
if strings.Contains(preview, "\n") {
t.Fatalf("expected flattened whitespace, got %q", preview)
@@ -344,7 +344,22 @@ func TestPreviewCommandOutputFlattensAndTruncates(t *testing.T) {
if !strings.HasPrefix(preview, "line one line two line three ") {
t.Fatalf("unexpected preview prefix: %q", preview)
}
if !strings.HasSuffix(preview, "...") {
t.Fatalf("expected truncation suffix, got %q", preview)
if !strings.Contains(preview, "... [truncated] ...") {
t.Fatalf("expected truncation marker, got %q", preview)
}
if !strings.HasSuffix(preview, "final api error 429") {
t.Fatalf("expected retained error tail, got %q", preview)
}
}
func TestPreviewCommandOutputRetainsStderrTail(t *testing.T) {
stdout := "startup banner " + strings.Repeat("x", 1200)
stderr := "provider api error 429"
preview := previewCommandOutput(stdout, stderr)
if !strings.HasPrefix(preview, "startup banner ") {
t.Fatalf("unexpected preview prefix: %q", preview)
}
if !strings.HasSuffix(preview, stderr) {
t.Fatalf("expected retained stderr tail, got %q", preview)
}
}