diff --git a/CHANGELOG.md b/CHANGELOG.md index bc74fc7e9b8..2f3319ff152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai - Workspace/oc-path: add the `oc://` addressing substrate (`src/oc-path/`) — a universal, kind-dispatched path scheme for addressing leaves and nodes inside markdown, jsonc, jsonl, and yaml workspace files, with `parseOcPath`/`formatOcPath`, per-kind `parseXxx`/`emitXxx`, universal `resolveOcPath`/`setOcPath`/`findOcPaths` verbs, the `__OPENCLAW_REDACTED__` sentinel emit guard, and the new `openclaw path resolve|find|set|validate|emit` CLI for shell-level inspection and surgical edits. Implements #78051. (#78678) Thanks @giodl73-repo. - Runtime/performance: avoid full-array sorting while auto-selecting providers, resolving supported thinking levels, picking node last-seen timestamps, and extracting Codex usage-limit messages. Thanks @shakkernerd. - Plugins/doctor: avoid full-array sorting while selecting ClawHub search/archive results and bounded dreaming doctor entries. Thanks @shakkernerd. +- Agents/compaction: keep contributor diagnostics to a bounded top-three selection without sorting the full history. Thanks @shakkernerd. - Telegram: preserve the channel-specific 10-option poll cap in the unified outbound adapter so over-limit polls are rejected before send. (#78762) Thanks @obviyus. - Slack: route handled top-level channel turns in implicit-conversation channels to thread-scoped sessions when Slack reply threading is enabled, keeping the root turn and later thread replies on one OpenClaw session. (#78522) Thanks @zeroth-blip. - Telegram: re-probe the primary fetch transport after repeated sticky fallback success so transient IPv4 or pinned-IP fallback promotion can recover without a gateway restart. Fixes #77088. (#77157) Thanks @MkDev11. diff --git a/src/agents/pi-embedded-runner/compact.ts b/src/agents/pi-embedded-runner/compact.ts index 1ebc6e00af6..79810272482 100644 --- a/src/agents/pi-embedded-runner/compact.ts +++ b/src/agents/pi-embedded-runner/compact.ts @@ -323,10 +323,34 @@ function summarizeCompactionMessages(messages: AgentMessage[]): CompactionMessag historyTextChars, toolResultChars, estTokens: tokenEstimationFailed ? undefined : estTokens, - contributors: contributors.toSorted((a, b) => b.chars - a.chars).slice(0, 3), + contributors: selectTopContributors(contributors), }; } +function selectTopContributors( + contributors: CompactionMessageMetrics["contributors"], +): CompactionMessageMetrics["contributors"] { + const selected: CompactionMessageMetrics["contributors"] = []; + for (const contributor of contributors) { + let insertAt = selected.length; + for (let index = 0; index < selected.length; index += 1) { + if (contributor.chars > selected[index].chars) { + insertAt = index; + break; + } + } + if (insertAt < 3) { + selected.splice(insertAt, 0, contributor); + if (selected.length > 3) { + selected.pop(); + } + } else if (selected.length < 3) { + selected.push(contributor); + } + } + return selected; +} + function containsRealConversationMessages(messages: AgentMessage[]): boolean { return messages.some((message, index, allMessages) => hasRealConversationContent(message, allMessages, index),