Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ APP_LOG_TO_FILE=true
# bodies is retained in the database.
# Used by: open-sse/handlers/chatCore.ts — cloneBoundedChatLogPayload()
# CHAT_LOG_TEXT_LIMIT=65536 # Max string length before truncation (default: 64 KB)
# CHAT_LOG_ARRAY_TAIL_ITEMS=24 # Number of array items retained from tail (default: 24)
# CHAT_LOG_ARRAY_TAIL_ITEMS=128 # Number of array items retained from tail (default: 128)
# CHAT_LOG_MAX_DEPTH=6 # Max nesting depth before truncation (default: 6)
# CHAT_LOG_MAX_OBJECT_KEYS=80 # Max object keys retained (default: 80, 0 = no limit)

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ The logging system writes to both stdout and rotated log files. All configuratio
| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Max rows in the `proxy_logs` SQLite table before pruning. |
| `APP_LOG_ROTATION_CHECK_INTERVAL_MS` | `60000` (1 min) | How often `src/lib/logRotation.ts` re-checks the active log file size. |
| `CHAT_LOG_TEXT_LIMIT` | `65536` | Max string length retained in chat log artifacts (default 64 KB). |
| `CHAT_LOG_ARRAY_TAIL_ITEMS` | `24` | Number of array items retained from the tail when truncating chat log payloads. |
| `CHAT_LOG_ARRAY_TAIL_ITEMS` | `128` | Number of array items retained from the tail when truncating chat log payloads. |
| `CHAT_LOG_MAX_DEPTH` | `6` | Max nesting depth before chat log payloads are truncated. |
| `CHAT_LOG_MAX_OBJECT_KEYS` | `80` | Max object keys retained in chat log payloads (0 = unlimited). |
| `CHAT_DEBUG_FILE` | `false` | When true, `serializeArtifactForStorage` skips size-based truncation. Debug only. |
Expand Down
13 changes: 12 additions & 1 deletion src/lib/logEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,19 @@ export function getChatLogTextLimit(): number {
return parsePositiveInt(process.env.CHAT_LOG_TEXT_LIMIT, 64 * 1024);
}

/**
* Was a hardcoded/default 24 — real agentic CLIs with many MCP servers
* routinely declare 40-50+ tools in a single `tools[]` array (a live
* OpenClaw session logged 47), so the tail-24 default silently dropped the
* array's earlier entries behind an `_omniroute_truncated_array` marker —
* including, in one traced case, the tool actually being called
* (`apply_patch`), making its declared shape unrecoverable from the call
* log even though the call itself succeeded. Bumped to comfortably cover
* real large tool lists with headroom; same configurable-override pattern
* as the sibling CHAT_LOG_TEXT_LIMIT/CHAT_LOG_MAX_BODY_KB vars.
*/
export function getChatLogArrayTailItems(): number {
return parsePositiveInt(process.env.CHAT_LOG_ARRAY_TAIL_ITEMS, 24);
return parsePositiveInt(process.env.CHAT_LOG_ARRAY_TAIL_ITEMS, 128);
}

export function getChatLogMaxDepth(): number {
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/chat-log-array-tail-items-default.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Regression test for the CHAT_LOG_ARRAY_TAIL_ITEMS default bump 24 -> 128.
*
* Real agentic CLIs with many MCP servers routinely declare 40-50+ tools in
* a single request — a live OpenClaw session logged 47. The old tail-24
* default silently dropped the array's earlier entries behind an
* `_omniroute_truncated_array` marker, including (in one traced case) the
* tool actually being called, making its declared shape unrecoverable from
* the call log even though the call itself succeeded.
*
* Pins the literal default so a future edit can't silently regress it back
* toward the old, too-small value.
*/
import { test } from "node:test";
import assert from "node:assert/strict";
import { getChatLogArrayTailItems } from "@/lib/logEnv";

test("getChatLogArrayTailItems defaults to 128 (not the old 24) when unset", () => {
const saved = process.env.CHAT_LOG_ARRAY_TAIL_ITEMS;
delete process.env.CHAT_LOG_ARRAY_TAIL_ITEMS;
try {
assert.equal(getChatLogArrayTailItems(), 128);
} finally {
if (saved === undefined) delete process.env.CHAT_LOG_ARRAY_TAIL_ITEMS;
else process.env.CHAT_LOG_ARRAY_TAIL_ITEMS = saved;
}
});
Loading