{"type":"system","subtype":"init","cwd":"./bench/results/mcp-with-toolsearch/weekly_catchup/run2/workspace","session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","tools":["Task","TaskOutput","Bash","Glob","Grep","ExitPlanMode","Read","Edit","Write","NotebookEdit","WebFetch","TodoWrite","WebSearch","TaskStop","AskUserQuestion","Skill","EnterPlanMode","EnterWorktree","ExitWorktree","CronCreate","CronDelete","CronList","ToolSearch","mcp__chrome-devtools__click","mcp__chrome-devtools__close_page","mcp__chrome-devtools__drag","mcp__chrome-devtools__emulate","mcp__chrome-devtools__evaluate_script","mcp__chrome-devtools__fill","mcp__chrome-devtools__fill_form","mcp__chrome-devtools__get_console_message","mcp__chrome-devtools__get_network_request","mcp__chrome-devtools__handle_dialog","mcp__chrome-devtools__hover","mcp__chrome-devtools__lighthouse_audit","mcp__chrome-devtools__list_console_messages","mcp__chrome-devtools__list_network_requests","mcp__chrome-devtools__list_pages","mcp__chrome-devtools__navigate_page","mcp__chrome-devtools__new_page","mcp__chrome-devtools__performance_analyze_insight","mcp__chrome-devtools__performance_start_trace","mcp__chrome-devtools__performance_stop_trace","mcp__chrome-devtools__press_key","mcp__chrome-devtools__resize_page","mcp__chrome-devtools__select_page","mcp__chrome-devtools__take_memory_snapshot","mcp__chrome-devtools__take_screenshot","mcp__chrome-devtools__take_snapshot","mcp__chrome-devtools__type_text","mcp__chrome-devtools__upload_file","mcp__chrome-devtools__wait_for","mcp__github__add_comment_to_pending_review","mcp__github__add_issue_comment","mcp__github__add_reply_to_pull_request_comment","mcp__github__assign_copilot_to_issue","mcp__github__create_branch","mcp__github__create_or_update_file","mcp__github__create_pull_request","mcp__github__create_pull_request_with_copilot","mcp__github__create_repository","mcp__github__delete_file","mcp__github__fork_repository","mcp__github__get_commit","mcp__github__get_copilot_job_status","mcp__github__get_file_contents","mcp__github__get_label","mcp__github__get_latest_release","mcp__github__get_me","mcp__github__get_release_by_tag","mcp__github__get_tag","mcp__github__get_team_members","mcp__github__get_teams","mcp__github__issue_read","mcp__github__issue_write","mcp__github__list_branches","mcp__github__list_commits","mcp__github__list_issue_types","mcp__github__list_issues","mcp__github__list_pull_requests","mcp__github__list_releases","mcp__github__list_tags","mcp__github__merge_pull_request","mcp__github__pull_request_read","mcp__github__pull_request_review_write","mcp__github__push_files","mcp__github__request_copilot_review","mcp__github__run_secret_scanning","mcp__github__search_code","mcp__github__search_issues","mcp__github__search_pull_requests","mcp__github__search_repositories","mcp__github__search_users","mcp__github__sub_issue_write","mcp__github__update_pull_request","mcp__github__update_pull_request_branch","ListMcpResourcesTool","ReadMcpResourceTool","LSP"],"mcp_servers":[{"name":"chrome-devtools","status":"connected"},{"name":"github","status":"connected"},{"name":"claude.ai Google Calendar","status":"needs-auth"},{"name":"claude.ai Gmail","status":"needs-auth"}],"model":"claude-sonnet-4-6","permissionMode":"bypassPermissions","slash_commands":["update-config","debug","simplify","batch","loop","claude-api","test-driven-development","app-installer","release-notify-issues","cli-demo-recorder","readme-generator","compact","context","cost","heapdump","init","pr-comments","release-notes","review","security-review","extra-usage","insights","mcp__github__AssignCodingAgent","mcp__github__issue_to_fix_workflow"],"apiKeySource":"none","claude_code_version":"2.1.77","output_style":"default","agents":["general-purpose","statusline-setup","Explore","Plan","claude-code-guide"],"skills":["update-config","debug","simplify","batch","loop","claude-api","test-driven-development","app-installer","release-notify-issues","cli-demo-recorder","readme-generator"],"plugins":[{"name":"rust-analyzer-lsp","path":"~/.claude/plugins/rust-analyzer-lsp/1.0.0"}],"uuid":"bb12f7a6-ce6f-4162-9504-0d0c329321ce","fast_mode_state":"off"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_017vnM341qMUyyGsdTF7uuiS","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"The user wants information about the openclaw/openclaw repository. I need to:\n1. Get the count of open issues\n2. Get the 5 most recently merged PRs\n3. Get the latest release tag\n\nI should use the MCP GitHub tools for this. Let me fetch the tool schemas first.","signature":"EqkDCkYICxgCKkBmrrsh5TUPP5wSAdwZwbdEz/jx6yFzd1a3T9ZijixUcbe0Zonu20Mpw5Dopwiw9drbebKYZH8W+ibPPSQy3u86EgzqmUNYIwSSlT5ApNoaDL2u1I2epg2ik8pjliIwHtcVwisEhAmQHVOdS4snEQXQUhHQNwRh54GIzAQLvW5XlqIDPDHnYQdioEXJsEbgKpACab8et8oVtj6F9hPtAS7XwR2IsqeplJpoYZGFUJZTWPk0tBqEBHXs30ZArLw/2sFc9nOlZnzRiDC2LSXNQaqJ9LgGyTf9FiLceG82tAYqCPP5F3Y/i/vsC2ft884wWOORgIidI/Unlf2mQeV8yiX3uAFs1anv7r3Aqxkgt/vek3TnYHSUyd3l9s49m8FwVBu4eMoPB4KzDw0q1KBAK1Cvqb3uLYbqI9vfGHznn/ZEjM65ps5BBnbWz/rovGNybEeXITvbNqKJOo74Pih+p7xU0bNMjKHKlW3CtvRQ6rrUnPvvB+xpKEm6bWhGOfGliR7PS5GY6+OUlonO5FGrgr+NCLLF0vOBeHZ1BTlK3P1AA1oYAQ=="}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":7836,"cache_read_input_tokens":8598,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":7836},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"bd391d0d-09d3-4cd0-84b0-7672d21736bc"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_017vnM341qMUyyGsdTF7uuiS","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01PBvu4KvXwdTjYeFafSZVJQ","name":"ToolSearch","input":{"query":"select:mcp__github__list_issues,mcp__github__list_pull_requests,mcp__github__get_latest_release","max_results":3},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":7836,"cache_read_input_tokens":8598,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":7836},"output_tokens":0,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"3b10ec1d-7d88-4b58-a561-9517ebb0f152"}
{"type":"user","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_01PBvu4KvXwdTjYeFafSZVJQ","content":[{"type":"tool_reference","tool_name":"mcp__github__list_issues"},{"type":"tool_reference","tool_name":"mcp__github__list_pull_requests"},{"type":"tool_reference","tool_name":"mcp__github__get_latest_release"}]}]},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"37a75574-6828-44ba-b90a-fe5c17c7dbac","timestamp":"2026-03-21T19:25:02.425Z","tool_use_result":{"matches":["mcp__github__list_issues","mcp__github__list_pull_requests","mcp__github__get_latest_release"],"query":"select:mcp__github__list_issues,mcp__github__list_pull_requests,mcp__github__get_latest_release","total_deferred_tools":90}}
{"type":"rate_limit_event","rate_limit_info":{"status":"allowed","resetsAt":1774126800,"rateLimitType":"five_hour","overageStatus":"rejected","overageDisabledReason":"org_level_disabled","isUsingOverage":false},"uuid":"d6c9a458-4f38-4c8c-8530-ecb3e413c208","session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_012YNpy64Edm8bbtYqtyyxeJ","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Now let me fetch all three pieces of information in parallel.","signature":"EuUBCkYICxgCKkD8ZXFtBVn8Zxc2QK5+50piH46bd2ufdZURzQAQ+mlu2JAv5Vje9idcmxF4SoK59TCbEKAY+TbLMkJOaALHLL6qEgxzAqSSbJEeH3ql3FgaDBW2wsH0WcZdx52MYCIwI4eTtR3ugieBQXTL6QfQoFIRNNjhsVLEPeiXwlU7qwKa88epP1bbOmcdqWhdIOM1Kk3Kt1D3Em9iphnEPqjwXwPA9NV/iUtRdKyQTUaB3irsOPYUV56iNw0pWPwPHdQ8rrhrUgRkirZXy5YoXYqigyxN59Blf1Ph7rvTUleyhRgB"}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":1001,"cache_read_input_tokens":16434,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":1001},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"e216a9ae-7257-4cea-b650-a44743189f58"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_012YNpy64Edm8bbtYqtyyxeJ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01JGJ6Pn2hJDrzHsyEw28Sdh","name":"mcp__github__list_issues","input":{"owner":"openclaw","repo":"openclaw","state":"OPEN","perPage":1},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":1001,"cache_read_input_tokens":16434,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":1001},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"8c0034e7-a413-4460-bcdf-da7fc87d713a"}
{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01JGJ6Pn2hJDrzHsyEw28Sdh","type":"tool_result","content":[{"type":"text","text":"{\"issues\":[{\"number\":51837,\"title\":\"Windows: exec spawns steal focus from active window\",\"body\":\"## Description\\n\\nOn native Windows (not WSL), commands spawned via the `exec` tool open visible command windows that steal focus from whatever the user is actively working on. This is disruptive during normal use — typing gets interrupted, windows flash, etc.\\n\\n## Current behavior\\n\\n- `exec` tool spawns processes that create visible console windows on Windows\\n- These windows steal focus from the active application\\n- Particularly disruptive during heartbeat checks when the user is working\\n\\n## Expected behavior\\n\\nAll exec spawns should use `windowsHide: true` (or equivalent) by default on Windows, so command windows never appear or steal focus.\\n\\n## Notes\\n\\n- ACP agent spawns and daemon processes already use `windowsHide: true` — this is just missing for regular `exec` calls\\n- Platform: Windows 11 (MINGW64_NT-10.0-26200), native install (not WSL)\\n- OpenClaw version: v2026.3.13\\n\\n## Environment\\n\\n- OS: Windows 11 (build 26200)\\n- Node: v24.14.0\\n- Shell: PowerShell\",\"state\":\"OPEN\",\"user\":{\"login\":\"junkyard-rules\"},\"created_at\":\"2026-03-21T19:22:35Z\",\"updated_at\":\"2026-03-21T19:22:35Z\"}],\"totalCount\":8780,\"pageInfo\":{\"hasNextPage\":true,\"hasPreviousPage\":false,\"startCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoyMjozNS0wNzowMM71L2nY\",\"endCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoyMjozNS0wNzowMM71L2nY\"}}"}]}]},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"4a1e72a3-c4c4-42d9-9c2c-0a5cbdb3bcd6","timestamp":"2026-03-21T19:25:05.997Z","tool_use_result":[{"type":"text","text":"{\"issues\":[{\"number\":51837,\"title\":\"Windows: exec spawns steal focus from active window\",\"body\":\"## Description\\n\\nOn native Windows (not WSL), commands spawned via the `exec` tool open visible command windows that steal focus from whatever the user is actively working on. This is disruptive during normal use — typing gets interrupted, windows flash, etc.\\n\\n## Current behavior\\n\\n- `exec` tool spawns processes that create visible console windows on Windows\\n- These windows steal focus from the active application\\n- Particularly disruptive during heartbeat checks when the user is working\\n\\n## Expected behavior\\n\\nAll exec spawns should use `windowsHide: true` (or equivalent) by default on Windows, so command windows never appear or steal focus.\\n\\n## Notes\\n\\n- ACP agent spawns and daemon processes already use `windowsHide: true` — this is just missing for regular `exec` calls\\n- Platform: Windows 11 (MINGW64_NT-10.0-26200), native install (not WSL)\\n- OpenClaw version: v2026.3.13\\n\\n## Environment\\n\\n- OS: Windows 11 (build 26200)\\n- Node: v24.14.0\\n- Shell: PowerShell\",\"state\":\"OPEN\",\"user\":{\"login\":\"junkyard-rules\"},\"created_at\":\"2026-03-21T19:22:35Z\",\"updated_at\":\"2026-03-21T19:22:35Z\"}],\"totalCount\":8780,\"pageInfo\":{\"hasNextPage\":true,\"hasPreviousPage\":false,\"startCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoyMjozNS0wNzowMM71L2nY\",\"endCursor\":\"Y3Vyc29yOnYyOpK5MjAyNi0wMy0yMVQxMjoyMjozNS0wNzowMM71L2nY\"}}"}]}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_012YNpy64Edm8bbtYqtyyxeJ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01HdX6vXtzDtBajWL1jDEwx1","name":"mcp__github__list_pull_requests","input":{"owner":"openclaw","repo":"openclaw","state":"closed","sort":"updated","direction":"desc","perPage":10},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":1001,"cache_read_input_tokens":16434,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":1001},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"652a1432-eb32-4dc6-842c-b7bd09ba9842"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_012YNpy64Edm8bbtYqtyyxeJ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01P7Lxks7ANB2mCDvkKJCJb5","name":"mcp__github__get_latest_release","input":{"owner":"openclaw","repo":"openclaw"},"caller":{"type":"direct"}}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":3,"cache_creation_input_tokens":1001,"cache_read_input_tokens":16434,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":1001},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"4fa9b570-4d29-4e20-bb04-47dec7bdcafa"}
{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01P7Lxks7ANB2mCDvkKJCJb5","type":"tool_result","content":[{"type":"text","text":"{\"tag_name\":\"v2026.3.13-1\",\"target_commitish\":\"61d171ab0b2fe4abc9afe89c518586274b4b76c2\",\"name\":\"openclaw 2026.3.13\",\"body\":\"This recovery release uses `v2026.3.13-1` because GitHub immutable releases do not allow reusing `v2026.3.13` after publication.\\r\\n\\r\\nImportant:\\r\\n- This release exists to recover the broken `v2026.3.13` tag/release path.\\r\\n- The corresponding npm version is still `2026.3.13`, not `2026.3.13-1`.\\r\\n- The `-1` suffix is for the Git tag and GitHub Release only.\\r\\n\\r\\n\\r\\n## What's Changed\\r\\n* fix(compaction): use full-session token count for post-compaction sanity check by @efe-arv in https://github.com/openclaw/openclaw/pull/28347\\r\\n* fix(telegram): thread media transport policy into SSRF by @obviyus in https://github.com/openclaw/openclaw/pull/44639\\r\\n* fix: handle Discord gateway metadata fetch failures by @jalehman in https://github.com/openclaw/openclaw/pull/44397\\r\\n* docs: move post-release changelog entries to Unreleased by @jalehman in https://github.com/openclaw/openclaw/pull/44691\\r\\n* fix(session): preserve `lastAccountId ` and `lastThreadId` on session reset by @Lanfei in https://github.com/openclaw/openclaw/pull/44773\\r\\n* Updated default model from openai-codex/gpt-5.3-codex to openai-codex/gpt-5.4 in tests. by @jrrcdev in https://github.com/openclaw/openclaw/pull/44367\\r\\n* fix: address delivery dedupe review follow-ups by @frankekn in https://github.com/openclaw/openclaw/pull/44666\\r\\n* CLI: align xhigh thinking help text by @frankekn in https://github.com/openclaw/openclaw/pull/44819\\r\\n* docs: fix changelog credit for xhigh help by @frankekn in https://github.com/openclaw/openclaw/pull/44874\\r\\n* fix(agents): drop Anthropic thinking blocks on replay by @frankekn in https://github.com/openclaw/openclaw/pull/44843\\r\\n* docs: fix session key :dm: → :direct: by @Lanfei in https://github.com/openclaw/openclaw/pull/26506\\r\\n* feat(android): redesign chat settings UI by @obviyus in https://github.com/openclaw/openclaw/pull/44894\\r\\n* fix(agents): avoid injecting memory file twice on case-insensitive mounts by @Lanfei in https://github.com/openclaw/openclaw/pull/26054\\r\\n* Docker: add OPENCLAW_TZ timezone support by @Lanfei in https://github.com/openclaw/openclaw/pull/34119\\r\\n* Android: fix HttpURLConnection leak in TalkModeVoiceResolver by @Kaneki-x in https://github.com/openclaw/openclaw/pull/43780\\r\\n* fix(agents): respect explicit user compat overrides for non-native openai-completions by @cheapestinference in https://github.com/openclaw/openclaw/pull/44432\\r\\n* test(config): cover requiresOpenAiAnthropicToolPayload in compat schema fixture by @xingsy97 in https://github.com/openclaw/openclaw/pull/43438\\r\\n* fix(agents): rephrase session reset prompt to avoid Azure content filter by @xingsy97 in https://github.com/openclaw/openclaw/pull/43403\\r\\n* fix(config): add missing params field to agents.list[] validation schema by @atian8179 in https://github.com/openclaw/openclaw/pull/41171\\r\\n* fix(android): use Google Code Scanner for onboarding QR by @obviyus in https://github.com/openclaw/openclaw/pull/45021\\r\\n* fix: restore web fetch firecrawl config in runtime zod schema by @stim64045-spec in https://github.com/openclaw/openclaw/pull/42583\\r\\n* fix(signal): add groups config to Signal channel schema by @unisone in https://github.com/openclaw/openclaw/pull/27199\\r\\n* feat(ios): add onboarding welcome pager by @ngutman in https://github.com/openclaw/openclaw/pull/45054\\r\\n* small addition to .gitignore  by @Sovtoshi-SC in https://github.com/openclaw/openclaw/pull/42879\\r\\n* fix(discovery): add missing domain to wideArea Zod config schema by @ingyukoh in https://github.com/openclaw/openclaw/pull/35615\\r\\n* fix(ui): keep shared auth on insecure control-ui connects by @velvet-shark in https://github.com/openclaw/openclaw/pull/45088\\r\\n* fix: preserve persona and language continuity in compaction summaries by @keepitmello in https://github.com/openclaw/openclaw/pull/10456\\r\\n* ui: mobile navigation drawer \\u0026 theme variant refinements by @BunsDev in https://github.com/openclaw/openclaw/pull/45107\\r\\n* fix: resolve target agent workspace for cross-agent subagent spawns by @moshehbenavraham in https://github.com/openclaw/openclaw/pull/40176\\r\\n* fix(ollama): hide native reasoning-only output by @frankekn in https://github.com/openclaw/openclaw/pull/45330\\r\\n* test: annotate chat abort helper exports by @frankekn in https://github.com/openclaw/openclaw/pull/45346\\r\\n* Fix incorrect rendering of brave costs in docs by @keelanfh in https://github.com/openclaw/openclaw/pull/44989\\r\\n* security(docker): prevent gateway token leak in Docker build context by @xingsy97 in https://github.com/openclaw/openclaw/pull/44956\\r\\n* refactor: remove redundant ?? undefined in Slack probe by @Cafexss in https://github.com/openclaw/openclaw/pull/44775\\r\\n* fix(ui): restore chat-new-messages class on scroll pill button by @Astro-Han in https://github.com/openclaw/openclaw/pull/44856\\r\\n* fix(windows): suppress visible console windows during restart and process cleanup by @MoerAI in https://github.com/openclaw/openclaw/pull/44842\\r\\n* Slack: add opt-in interactive reply directives by @vincentkoc in https://github.com/openclaw/openclaw/pull/44607\\r\\n* Docs: describe Slack interactive replies by @vincentkoc in https://github.com/openclaw/openclaw/pull/45463\\r\\n* fix(cron): prevent isolated cron nested lane deadlocks by @vincentkoc in https://github.com/openclaw/openclaw/pull/45459\\r\\n* Fix updater refresh cwd for service reinstall by @vincentkoc in https://github.com/openclaw/openclaw/pull/45452\\r\\n* [codex] Polish sidebar status, agent skills, and chat rendering by @BunsDev in https://github.com/openclaw/openclaw/pull/45451\\r\\n* perf(build): deduplicate plugin-sdk chunks to fix ~2x memory regression by @TarasShyn in https://github.com/openclaw/openclaw/pull/45426\\r\\n* Guard updater service refresh against missing invocation cwd by @vincentkoc in https://github.com/openclaw/openclaw/pull/45486\\r\\n* fix(browser): normalize batch act dispatch for selector and batch support by @vincentkoc in https://github.com/openclaw/openclaw/pull/45457\\r\\n* docs(android): note that app is not publicly released yet by @eengad in https://github.com/openclaw/openclaw/pull/23051\\r\\n* fix(browser): follow up batch failure and limit handling by @vincentkoc in https://github.com/openclaw/openclaw/pull/45506\\r\\n* docker: add apt-get upgrade to all Dockerfiles by @jacobtomlinson in https://github.com/openclaw/openclaw/pull/45384\\r\\n* fix(config): avoid Anthropic startup crash by @BunsDev in https://github.com/openclaw/openclaw/pull/45520\\r\\n* test: preserve wrapper behavior for targeted runs by @Takhoffman in https://github.com/openclaw/openclaw/pull/45518\\r\\n* UI: fix chat context notice icon sizing by @BunsDev in https://github.com/openclaw/openclaw/pull/45533\\r\\n* fix(ui): stop dashboard chat history reload storm by @BunsDev in https://github.com/openclaw/openclaw/pull/45541\\r\\n* fix: retry Telegram inbound media downloads over IPv4 fallback by @frankekn in https://github.com/openclaw/openclaw/pull/45327\\r\\n* fix(feishu): preserve non-ASCII filenames in file uploads (#33912) by @fabiaodemianyang in https://github.com/openclaw/openclaw/pull/34262\\r\\n* macOS: respect exec-approvals.json settings in gateway prompter by @sliekens in https://github.com/openclaw/openclaw/pull/13707\\r\\n* fix(ui): keep oversized chat replies readable by @BunsDev in https://github.com/openclaw/openclaw/pull/45559\\r\\n* fix(gateway/ui): restore control-ui auth bypass and classify connect failures by @sallyom in https://github.com/openclaw/openclaw/pull/45512\\r\\n* fix(macos): prevent PortGuard from killing Docker Desktop in remote mode by @teslamint in https://github.com/openclaw/openclaw/pull/13798\\r\\n* fix(sessions): create transcript file on chat.inject when missing by @2233admin in https://github.com/openclaw/openclaw/pull/36645\\r\\n* Plugins: fail fast on channel and binding collisions by @vincentkoc in https://github.com/openclaw/openclaw/pull/45628\\r\\n* fix(macos): align minimum Node.js version with runtime guard (22.16.0) by @ImLukeF in https://github.com/openclaw/openclaw/pull/45640\\r\\n* fix(agents): preserve blank local custom-provider API keys after onboarding by @frankekn in https://github.com/openclaw/openclaw/pull/45631\\r\\n* fix(browser): harden existing-session driver validation and session lifecycle by @odysseus0 in https://github.com/openclaw/openclaw/pull/45682\\r\\n* fix(feishu): add early event-level dedup to prevent duplicate replies by @yunweibang in https://github.com/openclaw/openclaw/pull/43762\\r\\n* fix(models): apply Gemini model-id normalization to google-vertex provider by @scoootscooob in https://github.com/openclaw/openclaw/pull/42435\\r\\n* Gateway: treat scope-limited probe RPC as degraded reachability by @joshavant in https://github.com/openclaw/openclaw/pull/45622\\r\\n* fix(gateway): bound unanswered client requests by @Takhoffman in https://github.com/openclaw/openclaw/pull/45689\\r\\n\\r\\n## New Contributors\\r\\n* @jrrcdev made their first contribution in https://github.com/openclaw/openclaw/pull/44367\\r\\n* @Kaneki-x made their first contribution in https://github.com/openclaw/openclaw/pull/43780\\r\\n* @cheapestinference made their first contribution in https://github.com/openclaw/openclaw/pull/44432\\r\\n* @xingsy97 made their first contribution in https://github.com/openclaw/openclaw/pull/43438\\r\\n* @atian8179 made their first contribution in https://github.com/openclaw/openclaw/pull/41171\\r\\n* @stim64045-spec made their first contribution in https://github.com/openclaw/openclaw/pull/42583\\r\\n* @Sovtoshi-SC made their first contribution in https://github.com/openclaw/openclaw/pull/42879\\r\\n* @keepitmello made their first contribution in https://github.com/openclaw/openclaw/pull/10456\\r\\n* @moshehbenavraham made their first contribution in https://github.com/openclaw/openclaw/pull/40176\\r\\n* @keelanfh made their first contribution in https://github.com/openclaw/openclaw/pull/44989\\r\\n* @Cafexss made their first contribution in https://github.com/openclaw/openclaw/pull/44775\\r\\n* @Astro-Han made their first contribution in https://github.com/openclaw/openclaw/pull/44856\\r\\n* @eengad made their first contribution in https://github.com/openclaw/openclaw/pull/23051\\r\\n* @jacobtomlinson made their first contribution in https://github.com/openclaw/openclaw/pull/45384\\r\\n* @fabiaodemianyang made their first contribution in https://github.com/openclaw/openclaw/pull/34262\\r\\n* @sliekens made their first contribution in https://github.com/openclaw/openclaw/pull/13707\\r\\n* @teslamint made their first contribution in https://github.com/openclaw/openclaw/pull/13798\\r\\n* @yunweibang made their first contribution in https://github.com/openclaw/openclaw/pull/43762\\r\\n\\r\\n**Full Changelog**: https://github.com/openclaw/openclaw/compare/v2026.3.12...v2026.3.13-1\",\"draft\":false,\"prerelease\":false,\"id\":297041210,\"created_at\":\"2026-03-14T18:03:51Z\",\"published_at\":\"2026-03-14T18:04:28Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210\",\"html_url\":\"https://github.com/openclaw/openclaw/releases/tag/v2026.3.13-1\",\"assets_url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210/assets\",\"upload_url\":\"https://uploads.github.com/repos/openclaw/openclaw/releases/297041210/assets{?name,label}\",\"zipball_url\":\"https://api.github.com/repos/openclaw/openclaw/zipball/v2026.3.13-1\",\"tarball_url\":\"https://api.github.com/repos/openclaw/openclaw/tarball/v2026.3.13-1\",\"author\":{\"login\":\"onutc\",\"id\":152018508,\"node_id\":\"U_kgDOCQ-eTA\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/152018508?v=4\",\"html_url\":\"https://github.com/onutc\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/onutc\",\"events_url\":\"https://api.github.com/users/onutc/events{/privacy}\",\"following_url\":\"https://api.github.com/users/onutc/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/onutc/followers\",\"gists_url\":\"https://api.github.com/users/onutc/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/onutc/orgs\",\"received_events_url\":\"https://api.github.com/users/onutc/received_events\",\"repos_url\":\"https://api.github.com/users/onutc/repos\",\"starred_url\":\"https://api.github.com/users/onutc/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/onutc/subscriptions\"},\"node_id\":\"RE_kwDOQb6kR84RtH06\",\"immutable\":true}"}]}]},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"cf92ed70-3275-43a1-aaf6-2a37ffca877c","timestamp":"2026-03-21T19:25:06.973Z","tool_use_result":[{"type":"text","text":"{\"tag_name\":\"v2026.3.13-1\",\"target_commitish\":\"61d171ab0b2fe4abc9afe89c518586274b4b76c2\",\"name\":\"openclaw 2026.3.13\",\"body\":\"This recovery release uses `v2026.3.13-1` because GitHub immutable releases do not allow reusing `v2026.3.13` after publication.\\r\\n\\r\\nImportant:\\r\\n- This release exists to recover the broken `v2026.3.13` tag/release path.\\r\\n- The corresponding npm version is still `2026.3.13`, not `2026.3.13-1`.\\r\\n- The `-1` suffix is for the Git tag and GitHub Release only.\\r\\n\\r\\n\\r\\n## What's Changed\\r\\n* fix(compaction): use full-session token count for post-compaction sanity check by @efe-arv in https://github.com/openclaw/openclaw/pull/28347\\r\\n* fix(telegram): thread media transport policy into SSRF by @obviyus in https://github.com/openclaw/openclaw/pull/44639\\r\\n* fix: handle Discord gateway metadata fetch failures by @jalehman in https://github.com/openclaw/openclaw/pull/44397\\r\\n* docs: move post-release changelog entries to Unreleased by @jalehman in https://github.com/openclaw/openclaw/pull/44691\\r\\n* fix(session): preserve `lastAccountId ` and `lastThreadId` on session reset by @Lanfei in https://github.com/openclaw/openclaw/pull/44773\\r\\n* Updated default model from openai-codex/gpt-5.3-codex to openai-codex/gpt-5.4 in tests. by @jrrcdev in https://github.com/openclaw/openclaw/pull/44367\\r\\n* fix: address delivery dedupe review follow-ups by @frankekn in https://github.com/openclaw/openclaw/pull/44666\\r\\n* CLI: align xhigh thinking help text by @frankekn in https://github.com/openclaw/openclaw/pull/44819\\r\\n* docs: fix changelog credit for xhigh help by @frankekn in https://github.com/openclaw/openclaw/pull/44874\\r\\n* fix(agents): drop Anthropic thinking blocks on replay by @frankekn in https://github.com/openclaw/openclaw/pull/44843\\r\\n* docs: fix session key :dm: → :direct: by @Lanfei in https://github.com/openclaw/openclaw/pull/26506\\r\\n* feat(android): redesign chat settings UI by @obviyus in https://github.com/openclaw/openclaw/pull/44894\\r\\n* fix(agents): avoid injecting memory file twice on case-insensitive mounts by @Lanfei in https://github.com/openclaw/openclaw/pull/26054\\r\\n* Docker: add OPENCLAW_TZ timezone support by @Lanfei in https://github.com/openclaw/openclaw/pull/34119\\r\\n* Android: fix HttpURLConnection leak in TalkModeVoiceResolver by @Kaneki-x in https://github.com/openclaw/openclaw/pull/43780\\r\\n* fix(agents): respect explicit user compat overrides for non-native openai-completions by @cheapestinference in https://github.com/openclaw/openclaw/pull/44432\\r\\n* test(config): cover requiresOpenAiAnthropicToolPayload in compat schema fixture by @xingsy97 in https://github.com/openclaw/openclaw/pull/43438\\r\\n* fix(agents): rephrase session reset prompt to avoid Azure content filter by @xingsy97 in https://github.com/openclaw/openclaw/pull/43403\\r\\n* fix(config): add missing params field to agents.list[] validation schema by @atian8179 in https://github.com/openclaw/openclaw/pull/41171\\r\\n* fix(android): use Google Code Scanner for onboarding QR by @obviyus in https://github.com/openclaw/openclaw/pull/45021\\r\\n* fix: restore web fetch firecrawl config in runtime zod schema by @stim64045-spec in https://github.com/openclaw/openclaw/pull/42583\\r\\n* fix(signal): add groups config to Signal channel schema by @unisone in https://github.com/openclaw/openclaw/pull/27199\\r\\n* feat(ios): add onboarding welcome pager by @ngutman in https://github.com/openclaw/openclaw/pull/45054\\r\\n* small addition to .gitignore  by @Sovtoshi-SC in https://github.com/openclaw/openclaw/pull/42879\\r\\n* fix(discovery): add missing domain to wideArea Zod config schema by @ingyukoh in https://github.com/openclaw/openclaw/pull/35615\\r\\n* fix(ui): keep shared auth on insecure control-ui connects by @velvet-shark in https://github.com/openclaw/openclaw/pull/45088\\r\\n* fix: preserve persona and language continuity in compaction summaries by @keepitmello in https://github.com/openclaw/openclaw/pull/10456\\r\\n* ui: mobile navigation drawer \\u0026 theme variant refinements by @BunsDev in https://github.com/openclaw/openclaw/pull/45107\\r\\n* fix: resolve target agent workspace for cross-agent subagent spawns by @moshehbenavraham in https://github.com/openclaw/openclaw/pull/40176\\r\\n* fix(ollama): hide native reasoning-only output by @frankekn in https://github.com/openclaw/openclaw/pull/45330\\r\\n* test: annotate chat abort helper exports by @frankekn in https://github.com/openclaw/openclaw/pull/45346\\r\\n* Fix incorrect rendering of brave costs in docs by @keelanfh in https://github.com/openclaw/openclaw/pull/44989\\r\\n* security(docker): prevent gateway token leak in Docker build context by @xingsy97 in https://github.com/openclaw/openclaw/pull/44956\\r\\n* refactor: remove redundant ?? undefined in Slack probe by @Cafexss in https://github.com/openclaw/openclaw/pull/44775\\r\\n* fix(ui): restore chat-new-messages class on scroll pill button by @Astro-Han in https://github.com/openclaw/openclaw/pull/44856\\r\\n* fix(windows): suppress visible console windows during restart and process cleanup by @MoerAI in https://github.com/openclaw/openclaw/pull/44842\\r\\n* Slack: add opt-in interactive reply directives by @vincentkoc in https://github.com/openclaw/openclaw/pull/44607\\r\\n* Docs: describe Slack interactive replies by @vincentkoc in https://github.com/openclaw/openclaw/pull/45463\\r\\n* fix(cron): prevent isolated cron nested lane deadlocks by @vincentkoc in https://github.com/openclaw/openclaw/pull/45459\\r\\n* Fix updater refresh cwd for service reinstall by @vincentkoc in https://github.com/openclaw/openclaw/pull/45452\\r\\n* [codex] Polish sidebar status, agent skills, and chat rendering by @BunsDev in https://github.com/openclaw/openclaw/pull/45451\\r\\n* perf(build): deduplicate plugin-sdk chunks to fix ~2x memory regression by @TarasShyn in https://github.com/openclaw/openclaw/pull/45426\\r\\n* Guard updater service refresh against missing invocation cwd by @vincentkoc in https://github.com/openclaw/openclaw/pull/45486\\r\\n* fix(browser): normalize batch act dispatch for selector and batch support by @vincentkoc in https://github.com/openclaw/openclaw/pull/45457\\r\\n* docs(android): note that app is not publicly released yet by @eengad in https://github.com/openclaw/openclaw/pull/23051\\r\\n* fix(browser): follow up batch failure and limit handling by @vincentkoc in https://github.com/openclaw/openclaw/pull/45506\\r\\n* docker: add apt-get upgrade to all Dockerfiles by @jacobtomlinson in https://github.com/openclaw/openclaw/pull/45384\\r\\n* fix(config): avoid Anthropic startup crash by @BunsDev in https://github.com/openclaw/openclaw/pull/45520\\r\\n* test: preserve wrapper behavior for targeted runs by @Takhoffman in https://github.com/openclaw/openclaw/pull/45518\\r\\n* UI: fix chat context notice icon sizing by @BunsDev in https://github.com/openclaw/openclaw/pull/45533\\r\\n* fix(ui): stop dashboard chat history reload storm by @BunsDev in https://github.com/openclaw/openclaw/pull/45541\\r\\n* fix: retry Telegram inbound media downloads over IPv4 fallback by @frankekn in https://github.com/openclaw/openclaw/pull/45327\\r\\n* fix(feishu): preserve non-ASCII filenames in file uploads (#33912) by @fabiaodemianyang in https://github.com/openclaw/openclaw/pull/34262\\r\\n* macOS: respect exec-approvals.json settings in gateway prompter by @sliekens in https://github.com/openclaw/openclaw/pull/13707\\r\\n* fix(ui): keep oversized chat replies readable by @BunsDev in https://github.com/openclaw/openclaw/pull/45559\\r\\n* fix(gateway/ui): restore control-ui auth bypass and classify connect failures by @sallyom in https://github.com/openclaw/openclaw/pull/45512\\r\\n* fix(macos): prevent PortGuard from killing Docker Desktop in remote mode by @teslamint in https://github.com/openclaw/openclaw/pull/13798\\r\\n* fix(sessions): create transcript file on chat.inject when missing by @2233admin in https://github.com/openclaw/openclaw/pull/36645\\r\\n* Plugins: fail fast on channel and binding collisions by @vincentkoc in https://github.com/openclaw/openclaw/pull/45628\\r\\n* fix(macos): align minimum Node.js version with runtime guard (22.16.0) by @ImLukeF in https://github.com/openclaw/openclaw/pull/45640\\r\\n* fix(agents): preserve blank local custom-provider API keys after onboarding by @frankekn in https://github.com/openclaw/openclaw/pull/45631\\r\\n* fix(browser): harden existing-session driver validation and session lifecycle by @odysseus0 in https://github.com/openclaw/openclaw/pull/45682\\r\\n* fix(feishu): add early event-level dedup to prevent duplicate replies by @yunweibang in https://github.com/openclaw/openclaw/pull/43762\\r\\n* fix(models): apply Gemini model-id normalization to google-vertex provider by @scoootscooob in https://github.com/openclaw/openclaw/pull/42435\\r\\n* Gateway: treat scope-limited probe RPC as degraded reachability by @joshavant in https://github.com/openclaw/openclaw/pull/45622\\r\\n* fix(gateway): bound unanswered client requests by @Takhoffman in https://github.com/openclaw/openclaw/pull/45689\\r\\n\\r\\n## New Contributors\\r\\n* @jrrcdev made their first contribution in https://github.com/openclaw/openclaw/pull/44367\\r\\n* @Kaneki-x made their first contribution in https://github.com/openclaw/openclaw/pull/43780\\r\\n* @cheapestinference made their first contribution in https://github.com/openclaw/openclaw/pull/44432\\r\\n* @xingsy97 made their first contribution in https://github.com/openclaw/openclaw/pull/43438\\r\\n* @atian8179 made their first contribution in https://github.com/openclaw/openclaw/pull/41171\\r\\n* @stim64045-spec made their first contribution in https://github.com/openclaw/openclaw/pull/42583\\r\\n* @Sovtoshi-SC made their first contribution in https://github.com/openclaw/openclaw/pull/42879\\r\\n* @keepitmello made their first contribution in https://github.com/openclaw/openclaw/pull/10456\\r\\n* @moshehbenavraham made their first contribution in https://github.com/openclaw/openclaw/pull/40176\\r\\n* @keelanfh made their first contribution in https://github.com/openclaw/openclaw/pull/44989\\r\\n* @Cafexss made their first contribution in https://github.com/openclaw/openclaw/pull/44775\\r\\n* @Astro-Han made their first contribution in https://github.com/openclaw/openclaw/pull/44856\\r\\n* @eengad made their first contribution in https://github.com/openclaw/openclaw/pull/23051\\r\\n* @jacobtomlinson made their first contribution in https://github.com/openclaw/openclaw/pull/45384\\r\\n* @fabiaodemianyang made their first contribution in https://github.com/openclaw/openclaw/pull/34262\\r\\n* @sliekens made their first contribution in https://github.com/openclaw/openclaw/pull/13707\\r\\n* @teslamint made their first contribution in https://github.com/openclaw/openclaw/pull/13798\\r\\n* @yunweibang made their first contribution in https://github.com/openclaw/openclaw/pull/43762\\r\\n\\r\\n**Full Changelog**: https://github.com/openclaw/openclaw/compare/v2026.3.12...v2026.3.13-1\",\"draft\":false,\"prerelease\":false,\"id\":297041210,\"created_at\":\"2026-03-14T18:03:51Z\",\"published_at\":\"2026-03-14T18:04:28Z\",\"url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210\",\"html_url\":\"https://github.com/openclaw/openclaw/releases/tag/v2026.3.13-1\",\"assets_url\":\"https://api.github.com/repos/openclaw/openclaw/releases/297041210/assets\",\"upload_url\":\"https://uploads.github.com/repos/openclaw/openclaw/releases/297041210/assets{?name,label}\",\"zipball_url\":\"https://api.github.com/repos/openclaw/openclaw/zipball/v2026.3.13-1\",\"tarball_url\":\"https://api.github.com/repos/openclaw/openclaw/tarball/v2026.3.13-1\",\"author\":{\"login\":\"onutc\",\"id\":152018508,\"node_id\":\"U_kgDOCQ-eTA\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/152018508?v=4\",\"html_url\":\"https://github.com/onutc\",\"gravatar_id\":\"\",\"type\":\"User\",\"site_admin\":false,\"url\":\"https://api.github.com/users/onutc\",\"events_url\":\"https://api.github.com/users/onutc/events{/privacy}\",\"following_url\":\"https://api.github.com/users/onutc/following{/other_user}\",\"followers_url\":\"https://api.github.com/users/onutc/followers\",\"gists_url\":\"https://api.github.com/users/onutc/gists{/gist_id}\",\"organizations_url\":\"https://api.github.com/users/onutc/orgs\",\"received_events_url\":\"https://api.github.com/users/onutc/received_events\",\"repos_url\":\"https://api.github.com/users/onutc/repos\",\"starred_url\":\"https://api.github.com/users/onutc/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/onutc/subscriptions\"},\"node_id\":\"RE_kwDOQb6kR84RtH06\",\"immutable\":true}"}]}
{"type":"user","message":{"role":"user","content":[{"tool_use_id":"toolu_01HdX6vXtzDtBajWL1jDEwx1","type":"tool_result","content":[{"type":"text","text":"[{\"number\":51833,\"title\":\"fix(server-maintenance): sweep orphaned chatRun buffers from stuck runs\",\"body\":\"## Problem\\n\\nWhen an LLM request times out without triggering a clean lifecycle end (e.g., embedded run timeout after 600s), `emitChatFinal` never fires and the streaming buffer in `chatRunState.buffers` persists indefinitely. The maintenance timer in `server-maintenance.ts` only cleans up runs that are in `chatRunState.abortedRuns` — stuck runs that were never explicitly aborted are missed.\\n\\nThis is the direct trigger for the `V8 StringAdd_CheckNone` OOM crash reported in #51821, since the stuck buffer holds a large concatenated string that can\\u0026#39;t be GC\\u0026#39;d.\\n\\nAdditionally, `chatRunState.deltaLastBroadcastLen` was only cleaned in `emitChatFinal` and was never passed to the maintenance timer at all, so it also accumulated entries from both aborted and stuck runs.\\n\\n## Fix\\n\\n1. **Orphaned buffer sweep**: After the existing aborted-run cleanup, iterate `chatDeltaSentAt` entries. Any entry older than `ABORTED_RUN_TTL_MS` (1 hour) that has no active `chatAbortController` is considered stuck — delete its buffer, deltaSentAt, and deltaLastBroadcastLen entries.\\n\\n2. **Thread `chatDeltaLastBroadcastLen`**: Expose the map through `server-runtime-state.ts` → `server.impl.ts` → `server-maintenance.ts` so it is cleaned in both the aborted-run sweep and the new orphaned-buffer sweep.\\n\\n## Files changed\\n\\n- `src/gateway/server-maintenance.ts` — add `chatDeltaLastBroadcastLen` param, orphaned buffer sweep\\n- `src/gateway/server-maintenance.test.ts` — add new param to test helper\\n- `src/gateway/server-runtime-state.ts` — expose `chatDeltaLastBroadcastLen`\\n- `src/gateway/server.impl.ts` — wire up new param\\n\\nCloses #51821\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51833\",\"user\":{\"login\":\"reed1898\",\"id\":129141816,\"profile_url\":\"https://github.com/reed1898\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/129141816?v=4\"},\"labels\":[\"gateway\",\"size: XS\",\"r: too-many-prs\"],\"head\":{\"ref\":\"fix/memleak-stuck-chatrun-buffer-sweep\",\"sha\":\"d0d3f6235ed7586856f69bb7ecf6f90ac97feb53\",\"repo\":{\"full_name\":\"reed1898/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"ef7a5c354611d37267a8309c62d706b2e1a345a3\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-21T19:13:22Z\",\"updated_at\":\"2026-03-21T19:18:09Z\",\"closed_at\":\"2026-03-21T19:13:46Z\"},{\"number\":51831,\"title\":\"fix(session-manager-cache): evict expired entries from SESSION_MANAGER_CACHE\",\"body\":\"## Problem\\n\\nThe `SESSION_MANAGER_CACHE` Map in `src/agents/pi-embedded-runner/session-manager-cache.ts` stores one entry per unique session file path. When `isSessionManagerCached()` finds a stale entry (TTL exceeded), it returned `false` but **never deleted the expired entry** from the Map. Entries accumulated indefinitely since `trackSessionManagerAccess()` only adds/updates and no code path ever calls `.delete()`.\\n\\nOn long-running gateways, this contributes to gradual heap growth.\\n\\n## Fix\\n\\nDelete the expired entry in `isSessionManagerCached()` before returning `false`. This keeps the Map bounded to the number of active (non-expired) session files — essentially a lazy-eviction strategy.\\n\\n## Diff\\n\\n```diff\\n function isSessionManagerCached(sessionFile: string): boolean {\\n   ...\\n   const now = Date.now();\\n   const ttl = getSessionManagerTtl();\\n-  return now - entry.loadedAt \\u0026lt;= ttl;\\n+  if (now - entry.loadedAt \\u0026gt; ttl) {\\n+    SESSION_MANAGER_CACHE.delete(sessionFile);\\n+    return false;\\n+  }\\n+  return true;\\n }\\n```\\n\\nCloses #51820\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51831\",\"user\":{\"login\":\"reed1898\",\"id\":129141816,\"profile_url\":\"https://github.com/reed1898\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/129141816?v=4\"},\"labels\":[\"agents\",\"size: XS\",\"r: too-many-prs\"],\"head\":{\"ref\":\"fix/memleak-session-manager-cache-eviction\",\"sha\":\"bffad5697b71f3f6a7a8305862d6f4e81e6eded1\",\"repo\":{\"full_name\":\"reed1898/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"ef7a5c354611d37267a8309c62d706b2e1a345a3\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-21T19:08:32Z\",\"updated_at\":\"2026-03-21T19:11:47Z\",\"closed_at\":\"2026-03-21T19:08:56Z\"},{\"number\":34222,\"title\":\"fix: use content hash for memory flush dedup instead of compactionCount (#30115)\",\"body\":\"## What\\nReplace event-based memory flush deduplication (`compactionCount`) with state-based deduplication (content hash) to prevent duplicate MEMORY.md writes when compaction aborts.\\n\\n## Why\\nFixes #30115 — Compaction abort triggers duplicate memory flushes in MEMORY.md.\\n\\nThe existing dedup uses `compactionCount` (an event counter) to decide whether to skip a flush. When compaction aborts and retries, the counter increments but the session context stays the same, causing the same content to be flushed repeatedly (4-7x duplicate entries reported).\\n\\nRoot cause: `compactionCount` conflates \\u0026#34;compaction cycle count\\u0026#34; with \\u0026#34;content has changed\\u0026#34; — these are independent concerns. Two different compaction cycles can see identical context (abort → retry scenario), so event-based dedup is fundamentally wrong for this use case.\\n\\n## How\\n- **State-based dedup**: compute a SHA-256 hash (truncated to 16 hex chars) of `messages.length + last 3 user/assistant message contents` before each flush. If the hash matches the stored `memoryFlushContextHash`, skip the flush.\\n- **Two-layer design**: `shouldRunMemoryFlush()` unchanged (token threshold gate), hash check added as second gate in `runMemoryFlushIfNeeded()`.\\n- **`willRetry` fix**: `onAgentEvent` now checks `!evt.data?.willRetry` before marking `memoryCompactionCompleted = true`, preventing retry-in-progress compaction from being incorrectly treated as completed.\\n- **Performance**: `readTranscriptTailMessages()` reads only the last 64KB of the transcript file (not the full file).\\n- **Hash timing**: stores the hash computed *before* the flush run (not after), since the flush turn itself writes to the transcript and would change the hash.\\n\\n### Scenario behavior\\n| Scenario | Behavior |\\n|----------|----------|\\n| Compaction abort | messages unchanged → hash unchanged → skip ✅ |\\n| Compaction success | messages compressed → hash changed → allow flush ✅ |\\n| New messages | tail content changed → hash changed → allow flush ✅ |\\n| Persistence failure | `contextHashBeforeFlush` used in-memory → no re-flush within session ✅ |\\n\\n## Files changed (3 + 1 test)\\n- `src/auto-reply/reply/memory-flush.ts` — new `computeContextHash()` function\\n- `src/auto-reply/reply/agent-runner-memory.ts` — hash check gate + willRetry fix + tail reader\\n- `src/config/sessions/types.ts` — add `memoryFlushContextHash` field to `SessionEntry`\\n- `src/auto-reply/reply/memory-flush.test.ts` — 8 unit tests for `computeContextHash`\\n\\n## Testing\\n- [x] `pnpm build` passes\\n- [x] `pnpm check` passes (lint + format)\\n- [x] `pnpm test` — 811/812 pass (1 pre-existing failure in `process-respawn.test.ts`)\\n- [x] 8 new unit tests for `computeContextHash` (empty input, object content, undefined content, system message filtering, length differentiation, tail behavior)\\n- [x] AI-assisted (OpenClaw agents 李飞飞/陈皮皮/毛豆豆, cross-reviewed, fully tested)\\n\\n## Backward compatibility\\n- `memoryFlushContextHash` undefined → falls back to existing `compactionCount` logic\\n- `memoryFlushCompactionCount` field preserved (not removed)\\n- First flush after upgrade runs normally (hash is empty = allow), subsequent flushes use hash dedup\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/34222\",\"user\":{\"login\":\"lml2468\",\"id\":39320777,\"profile_url\":\"https://github.com/lml2468\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/39320777?v=4\"},\"labels\":[\"cli\",\"size: M\"],\"assignees\":[\"jalehman\"],\"head\":{\"ref\":\"fix/memory-flush-dedup\",\"sha\":\"bce6f0bda03a203cd5c565d762334c8618197fc3\",\"repo\":{\"full_name\":\"lml2468/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fb50c98d672dd622887e1a60c1583e2e677ed324\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-04T09:13:16Z\",\"updated_at\":\"2026-03-21T19:06:26Z\",\"closed_at\":\"2026-03-21T19:06:26Z\",\"merged_at\":\"2026-03-21T19:06:26Z\"},{\"number\":51784,\"title\":\"fix: Control UI model picker provider prefix + skip register on snapshot loads\",\"body\":\"## Summary\\n\\nTwo fixes bundled together:\\n\\n### Fix 1: Control UI Model Picker Provider Prefix (#51608)\\n\\nFixes issue #51608 where the Control UI model picker sends wrong provider prefix for all models.\\n\\nWhen using the Control UI model picker to switch models, requests were incorrectly routed to the primary provider instead of the correct provider for each model when:\\n\\n1. A model has an alias configured in `agents.defaults.models`\\n2. The catalog entry has the alias as its `id` field\\n3. User selects the model, causing the UI to send `provider/alias` (e.g., `custom-dashscope-aliyuncs-com/bailian`)\\n\\nThe server\\u0026#39;s `resolveModelRefFromString` function parsed `provider/alias` correctly but didn\\u0026#39;t resolve the `alias` part through the alias index, causing the allowlist check to fail.\\n\\n**Changes:**\\n- `src/agents/model-selection.ts`: In `resolveModelRefFromString`, after parsing a qualified `provider/model` ref, check if the `model` part is an alias in the alias index. If so, use the alias\\u0026#39;s resolved model name instead.\\n- `src/agents/model-selection.test.ts`: Added test case for the bug fix.\\n\\n### Fix 2: Skip register() on Non-Activating Snapshot Loads (#51781)\\n\\nFixes issue #51781 where `loadOpenClawPlugins` with `activate: false` still invokes each plugin\\u0026#39;s `register()` function, causing performance overhead from repeated plugin initialization side effects during snapshot loads.\\n\\n**Changes:**\\n- `src/plugins/loader.ts`: Skip calling `register()` when `shouldActivate` is false (i.e., when `activate: false` is passed).\\n- `src/plugins/loader.test.ts`: Updated test to reflect the new expected behavior.\\n\\n## Testing\\n\\n- All `resolveModelRefFromString` tests pass (9 tests)\\n- All `sessions-patch` tests pass (27 tests)\\n- All `loader.test.ts` tests pass (77 tests)\\n- TypeScript type check passes\\n- Lint and format checks pass\\n\\nNote: One pre-existing test failure in `resolveConfiguredModelRef \\u0026gt; sanitizes control characters in providerless-model warnings` is unrelated to this change (Windows symlink permissions issue).\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51784\",\"user\":{\"login\":\"Yaohua-Leo\",\"id\":243496201,\"profile_url\":\"https://github.com/Yaohua-Leo\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/243496201?v=4\"},\"labels\":[\"agents\",\"size: S\"],\"head\":{\"ref\":\"fix/51608-ui-model-picker-provider-prefix\",\"sha\":\"2bc2a71dd24f2f87f8a60c64596be86a4971b31c\",\"repo\":{\"full_name\":\"Yaohua-Leo/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fb50c98d672dd622887e1a60c1583e2e677ed324\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-21T17:30:48Z\",\"updated_at\":\"2026-03-21T18:54:29Z\",\"closed_at\":\"2026-03-21T18:51:58Z\"},{\"number\":51200,\"title\":\"Pass runtime context into assemble\",\"body\":\"## Summary\\n\\n- Problem: `assemble()` only received a total `tokenBudget`, so context-engine plugins could not see host-owned prompt costs such as the base system prompt, tool schema, or the current user prompt.\\n- Why it matters: budget-aware memory engines had to guess how much context was already consumed by the host runtime, which made prompt budgeting less accurate and could lead to overly aggressive or overly loose memory injection.\\n- What changed:\\n  - added an optional `runtimeContext` field to `ContextEngine.assemble()`\\n  - passed runtime prompt budget signals from the embedded runner into `assemble()`\\n  - preserved legacy compatibility for engines that reject unknown fields like `runtimeContext`\\n  - added tests and docs for the new assemble input\\n- What did NOT change (scope boundary):\\n  - no change to memory plugin APIs\\n  - no change to retrieval behavior by itself\\n  - no forced behavior change for legacy engines beyond exposing optional metadata\\n\\n## Change Type\\n\\n- [x] Feature\\n- [x] Refactor required for the fix\\n- [x] Docs\\n\\n## Scope\\n\\n- [x] Gateway / orchestration\\n- [x] API / contracts\\n\\n## Linked Issue/PR\\n\\n- Related # N/A\\n\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51200\",\"user\":{\"login\":\"xiuminsama99\",\"id\":198452741,\"profile_url\":\"https://github.com/xiuminsama99\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/198452741?v=4\"},\"labels\":[\"docs\",\"cli\",\"commands\",\"agents\",\"size: XS\"],\"head\":{\"ref\":\"codex/assemble-runtime-context-budget\",\"sha\":\"d6367c2c55a2ef40f189300862d022b0276cc017\",\"repo\":{\"full_name\":\"xiuminsama99/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fb50c98d672dd622887e1a60c1583e2e677ed324\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T19:24:05Z\",\"updated_at\":\"2026-03-21T18:45:29Z\",\"closed_at\":\"2026-03-21T18:45:17Z\"},{\"number\":37080,\"title\":\"fix(tts): add matrix to VOICE_BUBBLE_CHANNELS\",\"body\":\"## Summary\\n\\n- Matrix TTS replies were sent as generic audio file attachments\\n- Missing from VOICE_BUBBLE_CHANNELS set in src/tts/tts.ts\\n- Enables native MSC3245 voice bubble support\\n\\n## Impact\\n\\nMatrix users configured with `messages.tts.auto: \\u0026#34;inbound\\u0026#34;` will now receive TTS replies as native voice message bubbles with:\\n- Waveform visualization\\n- Duration display\\n- Inline playback controls\\n\\nThis improves user experience for ~1500+ active Matrix users in the open-source community.\\n\\n## Root Cause\\n\\nMatrix channel was missing from VOICE_BUBBLE_CHANNELS, causing resolveOutputFormat() to skip voice-compatible settings. Although extensions/matrix/src/matrix/send.ts fully supports audioAsVoice and MSC3245 metadata, the TTS pipeline never set the flag.\\n\\n## Change\\n\\nAdded \\u0026#34;matrix\\u0026#34; to VOICE_BUBBLE_CHANNELS set:\\n- Before: [\\u0026#34;telegram\\u0026#34;, \\u0026#34;feishu\\u0026#34;, \\u0026#34;whatsapp\\u0026#34;]\\n- After: [\\u0026#34;telegram\\u0026#34;, \\u0026#34;feishu\\u0026#34;, \\u0026#34;whatsapp\\u0026#34;, \\u0026#34;matrix\\u0026#34;]\\n\\n## Test plan\\n\\n- [ ] Send voice message to bot on Matrix (Element)\\n- [ ] Verify TTS reply is sent as MSC3245 voice bubble, not generic file attachment\\n- [ ] Verify waveform, duration, and inline playback metadata present\\n\\nFixes #37061\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/37080\",\"user\":{\"login\":\"Matthew19990919\",\"id\":97017241,\"profile_url\":\"https://github.com/Matthew19990919\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/97017241?v=4\"},\"labels\":[\"channel: matrix\",\"size: S\"],\"assignees\":[\"gumadeiras\"],\"head\":{\"ref\":\"fix/matrix-voice-bubble-tts\",\"sha\":\"89ca0355d4c01e422b115cc83a64382b8c917284\",\"repo\":{\"full_name\":\"Matthew19990919/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fd2b3ed6af9c3ec6ee9e5e0f16410cf286159002\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-06T03:06:45Z\",\"updated_at\":\"2026-03-21T18:36:56Z\",\"closed_at\":\"2026-03-21T18:29:53Z\",\"merged_at\":\"2026-03-21T18:29:53Z\"},{\"number\":50819,\"title\":\"Tests: isolate remaining March 19 unit-fast OOM hotspots\",\"body\":\"## Summary\\n\\nDescribe the problem and fix in 2–5 bullets:\\n\\n- Problem: the March 19, 2026 Linux Node 24 `unit-fast` OOM lane still had two top memory-growth files missing from the scheduler behavior manifest on current `main`: `src/channels/channels-misc.test.ts` and `src/channels/plugins/outbound/slack.sendpayload.test.ts`.\\n- Why it matters: both files were among the top retained-heap contributors in GitHub Actions run `23327237169` / job `67850928311`, so leaving them in the shared `unit-fast` worker risks another worker-lifetime heap climb and OOM.\\n- What changed: add both files to `unit.singletonIsolated` in `test/fixtures/test-parallel.behavior.json` so they run in dedicated forks instead of the shared `unit-fast` lane.\\n- What did NOT change (scope boundary): no production code, test logic, timings manifest, or wrapper logic changed; this PR only adjusts the scheduler manifest.\\n\\n## Change Type (select all)\\n\\n- [x] Bug fix\\n- [ ] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [x] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [ ] Memory / storage\\n- [ ] Integrations\\n- [ ] API / contracts\\n- [ ] UI / DX\\n- [x] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\n- Closes: None\\n- Related: GitHub Actions run `23327237169`, job `67850928311`\\n\\n## User-visible / Behavior Changes\\n\\nNone.\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? (`Yes/No`) No\\n- Secrets/tokens handling changed? (`Yes/No`) No\\n- New/changed network calls? (`Yes/No`) No\\n- Command/tool execution surface changed? (`Yes/No`) No\\n- Data access scope changed? (`Yes/No`) No\\n- If any `Yes`, explain risk + mitigation:\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS 26.2\\n- Runtime/container: Node `v24.13.0`, local workspace\\n- Model/provider: N/A\\n- Integration/channel (if any): N/A\\n- Relevant config (redacted): `OPENCLAW_TEST_MEMORY_TRACE=1`, heap snapshots enabled for targeted diagnosis\\n\\n### Steps\\n\\n1. Inspect the failing CI log from run `23327237169` / job `67850928311` and note the top `unit-fast` memory deltas.\\n2. Reproduce the hotspot shape locally with repeated heap snapshots across the CI hotspot files.\\n3. Compare repeated snapshots from the same worker PID and classify the retained growth.\\n4. Add the still-missing hotspot files to `test/fixtures/test-parallel.behavior.json`.\\n5. Verify the wrapper now emits dedicated singleton lanes for those files.\\n\\n### Expected\\n\\n- `channels-misc` and `slack.sendpayload` no longer run inside the shared `unit-fast` lane.\\n\\n### Actual\\n\\n- Both files now appear as dedicated lanes: `channels-misc-isolated` and `slack.sendpayload-isolated`.\\n\\n## Evidence\\n\\nAttach at least one:\\n\\n- [x] Failing test/log before + passing after\\n- [x] Trace/log snippets\\n- [ ] Screenshot/recording\\n- [x] Perf numbers (if relevant)\\n\\nBefore:\\n\\n| Source | Lane | Result | Peak RSS | Total delta | Top relevant files |\\n| --- | --- | --- | --- | --- | --- |\\n| GitHub Actions run `23327237169` job `67850928311` | `unit-fast` | OOM | `13.36 GiB` | `+12.62 GiB` | `src/channels/channels-misc.test.ts:+412.5 MiB`, `src/channels/plugins/outbound/slack.sendpayload.test.ts:+319.0 MiB` |\\n\\nDiagnosis:\\n\\n- Reproduce command:\\n  ```bash\\n  OPENCLAW_TEST_MEMORY_TRACE=1 \\\\\\n  OPENCLAW_TEST_HEAPSNAPSHOT_INTERVAL_MS=5000 \\\\\\n  OPENCLAW_TEST_HEAPSNAPSHOT_DIR=.tmp/heapsnap-23327237169-r1 \\\\\\n  OPENCLAW_TEST_WORKERS=1 \\\\\\n  OPENCLAW_TEST_SERIAL_GATEWAY=1 \\\\\\n  pnpm test -- \\\\\\n    src/media-understanding/apply.test.ts \\\\\\n    src/node-host/invoke-system-run.test.ts \\\\\\n    src/channels/channels-misc.test.ts \\\\\\n    src/tui/tui.test.ts \\\\\\n    src/channels/plugins/outbound/slack.sendpayload.test.ts \\\\\\n    src/acp/translator.session-rate-limit.test.ts\\n  ```\\n- Compared lane/PID: `unit`, PID `31261`\\n- Snapshot delta finding: retained growth was dominated by Vite SSR transform strings such as `__vite_ssr_exportName__(...)`, which indicates shared-worker transformed-module retention rather than a runtime object leak.\\n\\nAfter:\\n\\n| Check | Result |\\n| --- | --- |\\n| `OPENCLAW_TEST_LIST_LANES=1 node scripts/test-parallel.mjs` | includes `channels-misc-isolated` |\\n| `OPENCLAW_TEST_LIST_LANES=1 node scripts/test-parallel.mjs` | includes `slack.sendpayload-isolated` |\\n| Local wrapper run after `pnpm canvas:a2ui:bundle` | `unit-fast` completed with `code=0`, `peak=3.28 GiB`, `totalDelta=+1.38 GiB` before the run moved on to singleton lanes |\\n\\n## Human Verification (required)\\n\\nWhat you personally verified (not just CI), and how:\\n\\n- Verified scenarios: inspected the failing CI log, reproduced the hotspot cluster with repeated heap snapshots, confirmed transformed-module retention, and verified the new singleton lanes appear in the wrapper.\\n- Edge cases checked: rebased onto current `upstream/main` and resolved overlap with newly added singleton entries so this PR only adds the still-missing files on top of current main.\\n- What you did **not** verify: I did not wait for a complete post-rebase `pnpm test` run to finish every remaining singleton lane after collecting the passing `unit-fast` summary.\\n\\n## Review Conversations\\n\\n- [x] I replied to or resolved every bot review conversation I addressed in this PR.\\n- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.\\n\\nIf a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? (`Yes/No`) Yes\\n- Config/env changes? (`Yes/No`) No\\n- Migration needed? (`Yes/No`) No\\n- If yes, exact upgrade steps:\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: revert this commit or remove the two entries from `test/fixtures/test-parallel.behavior.json`.\\n- Files/config to restore: `test/fixtures/test-parallel.behavior.json`\\n- Known bad symptoms reviewers should watch for: slightly longer overall test runtime from two additional singleton lanes.\\n\\n## Risks and Mitigations\\n\\nList only real risks for this PR. Add/remove entries as needed. If none, write `None`.\\n\\n- Risk: isolating two more files can modestly increase end-to-end suite time.\\n  - Mitigation: the change is narrowly scoped to the two CI-proven hotspot files that were still missing from the manifest.\\n\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/50819\",\"user\":{\"login\":\"huntharo\",\"id\":5617868,\"profile_url\":\"https://github.com/huntharo\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\"},\"labels\":[\"app: web-ui\",\"scripts\",\"maintainer\",\"size: L\"],\"head\":{\"ref\":\"codex/fix-unit-fast-oom-23327237169\",\"sha\":\"bf218ae75de2f5a1b7d7c6aad26e117532fa5deb\",\"repo\":{\"full_name\":\"huntharo/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"991eb2ef034fea1d6be52733d159a482aa0582af\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T03:55:35Z\",\"updated_at\":\"2026-03-21T18:30:50Z\",\"closed_at\":\"2026-03-21T18:30:50Z\"},{\"number\":51260,\"title\":\"Fix Discord `/codex_resume` picker expiration\",\"body\":\"## Summary\\n\\nDescribe the problem and fix in 2–5 bullets:\\n\\n- Problem: Discord `/codex_resume` picker buttons could immediately fail with `This component has expired.` even though the picker message had just been sent.\\n- Why it matters: resume-by-picker worked in Telegram but was broken in Discord, including the thread-in-channel-in-server flow used for real Codex resume.\\n- What changed: I kept the Discord fallback path from discarding explicit callback payloads, and I moved the Discord component registry onto process-global singleton maps so senders and listeners share the same component state across duplicate module instances.\\n- What did NOT change (scope boundary): I did not change the Codex app server picker generation logic; it was already emitting the expected `codexapp:` callbacks.\\n\\n## Change Type (select all)\\n\\n- [x] Bug fix\\n- [ ] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [ ] Memory / storage\\n- [x] Integrations\\n- [ ] API / contracts\\n- [x] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\n- Closes #\\n- Related #\\n\\n## User-visible / Behavior Changes\\n\\nDiscord Codex resume pickers now stay clickable and can successfully resume a session instead of immediately showing `This component has expired.`\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? (`No`)\\n- Secrets/tokens handling changed? (`No`)\\n- New/changed network calls? (`No`)\\n- Command/tool execution surface changed? (`No`)\\n- Data access scope changed? (`No`)\\n- If any `Yes`, explain risk + mitigation:\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: local dev checkout\\n- Model/provider: Codex app server integration\\n- Integration/channel (if any): Discord thread inside a channel inside a server\\n- Relevant config (redacted): Discord slash command flow with `/codex_resume`\\n\\n### Steps\\n\\n1. Run `/codex_resume` in a Discord thread.\\n2. Click `Browse Projects` or one of the recent-session buttons from the picker.\\n3. Repeat the interaction in the same Discord conversation.\\n\\n### Expected\\n\\n- The picker action is accepted and the selected Codex session view continues normally.\\n\\n### Actual\\n\\n- Before this fix, Discord responded with `This component has expired.` immediately after clicking the picker button.\\n\\n## Evidence\\n\\nAttach at least one:\\n\\n- [x] Failing test/log before + passing after\\n- [x] Trace/log snippets\\n- [x] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\n## Human Verification (required)\\n\\nWhat you personally verified (not just CI), and how:\\n\\n- Verified scenarios: I verified the Discord end-to-end `/codex_resume` flow, including clicking the picker in a Discord thread and successfully resuming a session.\\n- Edge cases checked: I also verified the focused Discord component tests covering callback fallback behavior and duplicate-module registry sharing.\\n- What you did **not** verify: I did not run the full `pnpm test` suite.\\n\\n## Review Conversations\\n\\n- [ ] I replied to or resolved every bot review conversation I addressed in this PR.\\n- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.\\n\\nIf a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? (`Yes`)\\n- Config/env changes? (`No`)\\n- Migration needed? (`No`)\\n- If yes, exact upgrade steps:\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: revert the two Discord component commits on this branch\\n- Files/config to restore: `extensions/discord/src/components-registry.ts`, `extensions/discord/src/monitor/agent-components.ts`\\n- Known bad symptoms reviewers should watch for: Discord component clicks failing to resolve, or plugin-owned pickers regressing to immediate `expired` responses\\n\\n## Risks and Mitigations\\n\\nList only real risks for this PR. Add/remove entries as needed. If none, write `None`.\\n\\n- Risk: sharing the registry globally could make stale component state survive duplicate module loads longer than before.\\n- Mitigation: the existing TTL and explicit clear/consume paths are unchanged, and I added a regression test for cross-module sharing.\\n\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51260\",\"user\":{\"login\":\"huntharo\",\"id\":5617868,\"profile_url\":\"https://github.com/huntharo\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\"},\"labels\":[\"channel: discord\",\"scripts\",\"maintainer\",\"size: L\"],\"assignees\":[\"huntharo\"],\"head\":{\"ref\":\"codex/fix-browse-projects-crash-discord\",\"sha\":\"76eb184dbe60cb1c05db02aab426a67b95095cc3\",\"repo\":{\"full_name\":\"huntharo/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"f4227e2787f3b85385f17e7d23decadd8575d478\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T20:30:04Z\",\"updated_at\":\"2026-03-21T18:30:22Z\",\"closed_at\":\"2026-03-21T16:59:22Z\",\"merged_at\":\"2026-03-21T16:59:21Z\"},{\"number\":40126,\"title\":\"feat(memory): pluggable system prompt section for memory plugins\",\"body\":\"## Summary\\n\\n- Problem: The system prompt \\u0026#34;Memory Recall\\u0026#34; section is hardcoded in `system-prompt.ts`, providing memory-core-specific instructions. When a third-party memory plugin is active (via the exclusive memory slot), these instructions are misleading.\\n- Why it matters: Third-party memory plugins need to provide their own system prompt guidance for their tools instead of the hardcoded memory-core instructions.\\n- What changed: Added `registerMemoryPromptSection(builder)` to the plugin API. The active memory plugin registers its own system prompt builder callback. Moved the existing \\u0026#34;Memory Recall\\u0026#34; logic into `memory-core` as its registration. `buildMemorySection()` delegates to the registered callback.\\n- What did NOT change (scope boundary): Default behavior is identical — memory-core registers the same prompt content. No changes to memory tools, compaction, or other plugin APIs.\\n\\n## Change Type (select all)\\n\\n- [ ] Bug fix\\n- [x] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [x] Memory / storage\\n- [ ] Integrations\\n- [x] API / contracts\\n- [ ] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\nNone\\n\\n## User-visible / Behavior Changes\\n\\nNone for default memory-core users. Memory plugins with `kind: \\u0026#34;memory\\u0026#34;` can now register a custom system prompt section via `api.registerMemoryPromptSection(builder)`.\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? No\\n- Secrets/tokens handling changed? No\\n- New/changed network calls? No\\n- Command/tool execution surface changed? No\\n- Data access scope changed? No\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: Bun\\n- Model/provider: N/A (system prompt wiring)\\n- Integration/channel (if any): Telegram (for human test)\\n\\n### Steps\\n\\n1. Install a memory plugin that calls `api.registerMemoryPromptSection(builder)`\\n2. Start a session\\n3. Observe that the system prompt contains the plugin\\u0026#39;s memory section instead of the hardcoded one\\n\\n### Expected\\n\\n- With memory-core (default): system prompt contains \\u0026#34;Memory Recall\\u0026#34; section as before\\n- With custom memory plugin: system prompt contains the plugin\\u0026#39;s custom section\\n- With no memory plugin: memory section is omitted\\n\\n### Actual (before fix)\\n\\n- Hardcoded \\u0026#34;Memory Recall\\u0026#34; section always present regardless of active memory plugin\\n\\n## Evidence\\n\\n- [x] Failing test/log before + passing after\\n- [ ] Trace/log snippets\\n- [ ] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\nNew unit tests in `prompt-section.test.ts`: delegation, citationsMode passthrough, no-builder returns empty, last-registration-wins. All 43 existing `system-prompt.test.ts` tests pass.\\n\\n## Human Verification (required)\\n\\n- Verified scenarios: Tested on two separate OpenClaw bots (Telegram) with memory-core active — memory instructions present as expected, no regression observed\\n- Edge cases checked: None\\n- What you did **not** verify: No memory plugin active (section omitted), custom third-party memory plugin providing its own section\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? Yes\\n- Config/env changes? No\\n- Migration needed? No\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: Revert the commit; hardcoded prompt returns\\n- Files/config to restore: N/A\\n- Known bad symptoms reviewers should watch for: Missing \\u0026#34;Memory Recall\\u0026#34; section in system prompt when memory-core is active\\n\\n## Risks and Mitigations\\n\\nNone. Additive API change. Default behavior is identical — memory-core registers the same prompt content it previously hardcoded.\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/40126\",\"user\":{\"login\":\"jarimustonen\",\"id\":1272053,\"profile_url\":\"https://github.com/jarimustonen\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/1272053?v=4\"},\"labels\":[\"extensions: lobster\",\"extensions: memory-core\",\"cli\",\"scripts\",\"agents\",\"size: M\"],\"assignees\":[\"jalehman\"],\"head\":{\"ref\":\"feat/memory-prompt-section-plugin-api\",\"sha\":\"5228d1937f037172762fa64b0f8749403f9ae85f\",\"repo\":{\"full_name\":\"jarimustonen/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"ebfc5f82408f0d592e45db62c61c4834d2cb07e6\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-08T17:38:46Z\",\"updated_at\":\"2026-03-21T18:20:45Z\",\"closed_at\":\"2026-03-21T18:20:45Z\",\"merged_at\":\"2026-03-21T18:20:45Z\"},{\"number\":51146,\"title\":\"fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux)\",\"body\":\"## Summary\\n\\n- Detect nvm-installed Node.js on Linux (via `NVM_DIR` env var or `process.execPath` containing `/.nvm/`)\\n- Auto-set `NODE_EXTRA_CA_CERTS` to the system CA bundle in the systemd service environment when nvm is detected on Linux (same pattern as the existing macOS default)\\n- Probe multiple distro-specific CA bundle paths (`/etc/ssl/certs/ca-certificates.crt` for Debian/Ubuntu/Alpine, `/etc/pki/tls/certs/ca-bundle.crt` for RHEL/Fedora/CentOS, `/etc/ssl/ca-bundle.pem` for openSUSE) — returns `undefined` when none exists, so `NODE_EXTRA_CA_CERTS` is never set to a missing path\\n- Write `NODE_EXTRA_CA_CERTS` to `~/.openclaw/.env` during `openclaw gateway install` so manual `gateway run` also picks up the system CA bundle via dotenv\\n- Backfill `.env` on the `already-installed` path so upgrading users get the entry without `--force`\\n- Injectable `platform`/`execPath` params throughout for testability\\n- Add documentation for nvm/VPS users with the manual workaround\\n\\nFixes #49088\\n\\n## Test plan\\n\\n- [x] `isNvmNode()` unit tests: NVM_DIR env detection, execPath detection, negative cases\\n- [x] `resolveLinuxSystemCaBundle()` probes multiple distro paths, returns undefined when none exists\\n- [x] Service env tests: NODE_EXTRA_CA_CERTS defaults on Linux with/without nvm, user override respected\\n- [x] `execPath` injectable in both `buildServiceEnvironment` and `buildNodeServiceEnvironment`\\n- [x] All 65 service-env tests pass\\n- [x] TypeScript typecheck passes (0 errors)\\n- [x] Lint/format passes\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51146\",\"user\":{\"login\":\"GodsBoy\",\"id\":5792287,\"profile_url\":\"https://github.com/GodsBoy\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5792287?v=4\"},\"labels\":[\"docs\",\"gateway\",\"cli\",\"size: L\"],\"head\":{\"ref\":\"fix/nvm-node-extra-ca-certs-v2\",\"sha\":\"2e6cf19c0f91e52e10e0c77b50b85d477f1594f7\",\"repo\":{\"full_name\":\"GodsBoy/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"d6367c2c55a2ef40f189300862d022b0276cc017\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T16:54:00Z\",\"updated_at\":\"2026-03-21T18:07:18Z\",\"closed_at\":\"2026-03-21T18:06:32Z\",\"merged_at\":\"2026-03-21T18:06:32Z\"}]"}]}]},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"33197c94-6bfe-4e8d-82c7-127442ff110c","timestamp":"2026-03-21T19:25:07.296Z","tool_use_result":[{"type":"text","text":"[{\"number\":51833,\"title\":\"fix(server-maintenance): sweep orphaned chatRun buffers from stuck runs\",\"body\":\"## Problem\\n\\nWhen an LLM request times out without triggering a clean lifecycle end (e.g., embedded run timeout after 600s), `emitChatFinal` never fires and the streaming buffer in `chatRunState.buffers` persists indefinitely. The maintenance timer in `server-maintenance.ts` only cleans up runs that are in `chatRunState.abortedRuns` — stuck runs that were never explicitly aborted are missed.\\n\\nThis is the direct trigger for the `V8 StringAdd_CheckNone` OOM crash reported in #51821, since the stuck buffer holds a large concatenated string that can\\u0026#39;t be GC\\u0026#39;d.\\n\\nAdditionally, `chatRunState.deltaLastBroadcastLen` was only cleaned in `emitChatFinal` and was never passed to the maintenance timer at all, so it also accumulated entries from both aborted and stuck runs.\\n\\n## Fix\\n\\n1. **Orphaned buffer sweep**: After the existing aborted-run cleanup, iterate `chatDeltaSentAt` entries. Any entry older than `ABORTED_RUN_TTL_MS` (1 hour) that has no active `chatAbortController` is considered stuck — delete its buffer, deltaSentAt, and deltaLastBroadcastLen entries.\\n\\n2. **Thread `chatDeltaLastBroadcastLen`**: Expose the map through `server-runtime-state.ts` → `server.impl.ts` → `server-maintenance.ts` so it is cleaned in both the aborted-run sweep and the new orphaned-buffer sweep.\\n\\n## Files changed\\n\\n- `src/gateway/server-maintenance.ts` — add `chatDeltaLastBroadcastLen` param, orphaned buffer sweep\\n- `src/gateway/server-maintenance.test.ts` — add new param to test helper\\n- `src/gateway/server-runtime-state.ts` — expose `chatDeltaLastBroadcastLen`\\n- `src/gateway/server.impl.ts` — wire up new param\\n\\nCloses #51821\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51833\",\"user\":{\"login\":\"reed1898\",\"id\":129141816,\"profile_url\":\"https://github.com/reed1898\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/129141816?v=4\"},\"labels\":[\"gateway\",\"size: XS\",\"r: too-many-prs\"],\"head\":{\"ref\":\"fix/memleak-stuck-chatrun-buffer-sweep\",\"sha\":\"d0d3f6235ed7586856f69bb7ecf6f90ac97feb53\",\"repo\":{\"full_name\":\"reed1898/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"ef7a5c354611d37267a8309c62d706b2e1a345a3\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-21T19:13:22Z\",\"updated_at\":\"2026-03-21T19:18:09Z\",\"closed_at\":\"2026-03-21T19:13:46Z\"},{\"number\":51831,\"title\":\"fix(session-manager-cache): evict expired entries from SESSION_MANAGER_CACHE\",\"body\":\"## Problem\\n\\nThe `SESSION_MANAGER_CACHE` Map in `src/agents/pi-embedded-runner/session-manager-cache.ts` stores one entry per unique session file path. When `isSessionManagerCached()` finds a stale entry (TTL exceeded), it returned `false` but **never deleted the expired entry** from the Map. Entries accumulated indefinitely since `trackSessionManagerAccess()` only adds/updates and no code path ever calls `.delete()`.\\n\\nOn long-running gateways, this contributes to gradual heap growth.\\n\\n## Fix\\n\\nDelete the expired entry in `isSessionManagerCached()` before returning `false`. This keeps the Map bounded to the number of active (non-expired) session files — essentially a lazy-eviction strategy.\\n\\n## Diff\\n\\n```diff\\n function isSessionManagerCached(sessionFile: string): boolean {\\n   ...\\n   const now = Date.now();\\n   const ttl = getSessionManagerTtl();\\n-  return now - entry.loadedAt \\u0026lt;= ttl;\\n+  if (now - entry.loadedAt \\u0026gt; ttl) {\\n+    SESSION_MANAGER_CACHE.delete(sessionFile);\\n+    return false;\\n+  }\\n+  return true;\\n }\\n```\\n\\nCloses #51820\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51831\",\"user\":{\"login\":\"reed1898\",\"id\":129141816,\"profile_url\":\"https://github.com/reed1898\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/129141816?v=4\"},\"labels\":[\"agents\",\"size: XS\",\"r: too-many-prs\"],\"head\":{\"ref\":\"fix/memleak-session-manager-cache-eviction\",\"sha\":\"bffad5697b71f3f6a7a8305862d6f4e81e6eded1\",\"repo\":{\"full_name\":\"reed1898/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"ef7a5c354611d37267a8309c62d706b2e1a345a3\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-21T19:08:32Z\",\"updated_at\":\"2026-03-21T19:11:47Z\",\"closed_at\":\"2026-03-21T19:08:56Z\"},{\"number\":34222,\"title\":\"fix: use content hash for memory flush dedup instead of compactionCount (#30115)\",\"body\":\"## What\\nReplace event-based memory flush deduplication (`compactionCount`) with state-based deduplication (content hash) to prevent duplicate MEMORY.md writes when compaction aborts.\\n\\n## Why\\nFixes #30115 — Compaction abort triggers duplicate memory flushes in MEMORY.md.\\n\\nThe existing dedup uses `compactionCount` (an event counter) to decide whether to skip a flush. When compaction aborts and retries, the counter increments but the session context stays the same, causing the same content to be flushed repeatedly (4-7x duplicate entries reported).\\n\\nRoot cause: `compactionCount` conflates \\u0026#34;compaction cycle count\\u0026#34; with \\u0026#34;content has changed\\u0026#34; — these are independent concerns. Two different compaction cycles can see identical context (abort → retry scenario), so event-based dedup is fundamentally wrong for this use case.\\n\\n## How\\n- **State-based dedup**: compute a SHA-256 hash (truncated to 16 hex chars) of `messages.length + last 3 user/assistant message contents` before each flush. If the hash matches the stored `memoryFlushContextHash`, skip the flush.\\n- **Two-layer design**: `shouldRunMemoryFlush()` unchanged (token threshold gate), hash check added as second gate in `runMemoryFlushIfNeeded()`.\\n- **`willRetry` fix**: `onAgentEvent` now checks `!evt.data?.willRetry` before marking `memoryCompactionCompleted = true`, preventing retry-in-progress compaction from being incorrectly treated as completed.\\n- **Performance**: `readTranscriptTailMessages()` reads only the last 64KB of the transcript file (not the full file).\\n- **Hash timing**: stores the hash computed *before* the flush run (not after), since the flush turn itself writes to the transcript and would change the hash.\\n\\n### Scenario behavior\\n| Scenario | Behavior |\\n|----------|----------|\\n| Compaction abort | messages unchanged → hash unchanged → skip ✅ |\\n| Compaction success | messages compressed → hash changed → allow flush ✅ |\\n| New messages | tail content changed → hash changed → allow flush ✅ |\\n| Persistence failure | `contextHashBeforeFlush` used in-memory → no re-flush within session ✅ |\\n\\n## Files changed (3 + 1 test)\\n- `src/auto-reply/reply/memory-flush.ts` — new `computeContextHash()` function\\n- `src/auto-reply/reply/agent-runner-memory.ts` — hash check gate + willRetry fix + tail reader\\n- `src/config/sessions/types.ts` — add `memoryFlushContextHash` field to `SessionEntry`\\n- `src/auto-reply/reply/memory-flush.test.ts` — 8 unit tests for `computeContextHash`\\n\\n## Testing\\n- [x] `pnpm build` passes\\n- [x] `pnpm check` passes (lint + format)\\n- [x] `pnpm test` — 811/812 pass (1 pre-existing failure in `process-respawn.test.ts`)\\n- [x] 8 new unit tests for `computeContextHash` (empty input, object content, undefined content, system message filtering, length differentiation, tail behavior)\\n- [x] AI-assisted (OpenClaw agents 李飞飞/陈皮皮/毛豆豆, cross-reviewed, fully tested)\\n\\n## Backward compatibility\\n- `memoryFlushContextHash` undefined → falls back to existing `compactionCount` logic\\n- `memoryFlushCompactionCount` field preserved (not removed)\\n- First flush after upgrade runs normally (hash is empty = allow), subsequent flushes use hash dedup\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/34222\",\"user\":{\"login\":\"lml2468\",\"id\":39320777,\"profile_url\":\"https://github.com/lml2468\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/39320777?v=4\"},\"labels\":[\"cli\",\"size: M\"],\"assignees\":[\"jalehman\"],\"head\":{\"ref\":\"fix/memory-flush-dedup\",\"sha\":\"bce6f0bda03a203cd5c565d762334c8618197fc3\",\"repo\":{\"full_name\":\"lml2468/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fb50c98d672dd622887e1a60c1583e2e677ed324\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-04T09:13:16Z\",\"updated_at\":\"2026-03-21T19:06:26Z\",\"closed_at\":\"2026-03-21T19:06:26Z\",\"merged_at\":\"2026-03-21T19:06:26Z\"},{\"number\":51784,\"title\":\"fix: Control UI model picker provider prefix + skip register on snapshot loads\",\"body\":\"## Summary\\n\\nTwo fixes bundled together:\\n\\n### Fix 1: Control UI Model Picker Provider Prefix (#51608)\\n\\nFixes issue #51608 where the Control UI model picker sends wrong provider prefix for all models.\\n\\nWhen using the Control UI model picker to switch models, requests were incorrectly routed to the primary provider instead of the correct provider for each model when:\\n\\n1. A model has an alias configured in `agents.defaults.models`\\n2. The catalog entry has the alias as its `id` field\\n3. User selects the model, causing the UI to send `provider/alias` (e.g., `custom-dashscope-aliyuncs-com/bailian`)\\n\\nThe server\\u0026#39;s `resolveModelRefFromString` function parsed `provider/alias` correctly but didn\\u0026#39;t resolve the `alias` part through the alias index, causing the allowlist check to fail.\\n\\n**Changes:**\\n- `src/agents/model-selection.ts`: In `resolveModelRefFromString`, after parsing a qualified `provider/model` ref, check if the `model` part is an alias in the alias index. If so, use the alias\\u0026#39;s resolved model name instead.\\n- `src/agents/model-selection.test.ts`: Added test case for the bug fix.\\n\\n### Fix 2: Skip register() on Non-Activating Snapshot Loads (#51781)\\n\\nFixes issue #51781 where `loadOpenClawPlugins` with `activate: false` still invokes each plugin\\u0026#39;s `register()` function, causing performance overhead from repeated plugin initialization side effects during snapshot loads.\\n\\n**Changes:**\\n- `src/plugins/loader.ts`: Skip calling `register()` when `shouldActivate` is false (i.e., when `activate: false` is passed).\\n- `src/plugins/loader.test.ts`: Updated test to reflect the new expected behavior.\\n\\n## Testing\\n\\n- All `resolveModelRefFromString` tests pass (9 tests)\\n- All `sessions-patch` tests pass (27 tests)\\n- All `loader.test.ts` tests pass (77 tests)\\n- TypeScript type check passes\\n- Lint and format checks pass\\n\\nNote: One pre-existing test failure in `resolveConfiguredModelRef \\u0026gt; sanitizes control characters in providerless-model warnings` is unrelated to this change (Windows symlink permissions issue).\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51784\",\"user\":{\"login\":\"Yaohua-Leo\",\"id\":243496201,\"profile_url\":\"https://github.com/Yaohua-Leo\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/243496201?v=4\"},\"labels\":[\"agents\",\"size: S\"],\"head\":{\"ref\":\"fix/51608-ui-model-picker-provider-prefix\",\"sha\":\"2bc2a71dd24f2f87f8a60c64596be86a4971b31c\",\"repo\":{\"full_name\":\"Yaohua-Leo/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fb50c98d672dd622887e1a60c1583e2e677ed324\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-21T17:30:48Z\",\"updated_at\":\"2026-03-21T18:54:29Z\",\"closed_at\":\"2026-03-21T18:51:58Z\"},{\"number\":51200,\"title\":\"Pass runtime context into assemble\",\"body\":\"## Summary\\n\\n- Problem: `assemble()` only received a total `tokenBudget`, so context-engine plugins could not see host-owned prompt costs such as the base system prompt, tool schema, or the current user prompt.\\n- Why it matters: budget-aware memory engines had to guess how much context was already consumed by the host runtime, which made prompt budgeting less accurate and could lead to overly aggressive or overly loose memory injection.\\n- What changed:\\n  - added an optional `runtimeContext` field to `ContextEngine.assemble()`\\n  - passed runtime prompt budget signals from the embedded runner into `assemble()`\\n  - preserved legacy compatibility for engines that reject unknown fields like `runtimeContext`\\n  - added tests and docs for the new assemble input\\n- What did NOT change (scope boundary):\\n  - no change to memory plugin APIs\\n  - no change to retrieval behavior by itself\\n  - no forced behavior change for legacy engines beyond exposing optional metadata\\n\\n## Change Type\\n\\n- [x] Feature\\n- [x] Refactor required for the fix\\n- [x] Docs\\n\\n## Scope\\n\\n- [x] Gateway / orchestration\\n- [x] API / contracts\\n\\n## Linked Issue/PR\\n\\n- Related # N/A\\n\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51200\",\"user\":{\"login\":\"xiuminsama99\",\"id\":198452741,\"profile_url\":\"https://github.com/xiuminsama99\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/198452741?v=4\"},\"labels\":[\"docs\",\"cli\",\"commands\",\"agents\",\"size: XS\"],\"head\":{\"ref\":\"codex/assemble-runtime-context-budget\",\"sha\":\"d6367c2c55a2ef40f189300862d022b0276cc017\",\"repo\":{\"full_name\":\"xiuminsama99/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fb50c98d672dd622887e1a60c1583e2e677ed324\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T19:24:05Z\",\"updated_at\":\"2026-03-21T18:45:29Z\",\"closed_at\":\"2026-03-21T18:45:17Z\"},{\"number\":37080,\"title\":\"fix(tts): add matrix to VOICE_BUBBLE_CHANNELS\",\"body\":\"## Summary\\n\\n- Matrix TTS replies were sent as generic audio file attachments\\n- Missing from VOICE_BUBBLE_CHANNELS set in src/tts/tts.ts\\n- Enables native MSC3245 voice bubble support\\n\\n## Impact\\n\\nMatrix users configured with `messages.tts.auto: \\u0026#34;inbound\\u0026#34;` will now receive TTS replies as native voice message bubbles with:\\n- Waveform visualization\\n- Duration display\\n- Inline playback controls\\n\\nThis improves user experience for ~1500+ active Matrix users in the open-source community.\\n\\n## Root Cause\\n\\nMatrix channel was missing from VOICE_BUBBLE_CHANNELS, causing resolveOutputFormat() to skip voice-compatible settings. Although extensions/matrix/src/matrix/send.ts fully supports audioAsVoice and MSC3245 metadata, the TTS pipeline never set the flag.\\n\\n## Change\\n\\nAdded \\u0026#34;matrix\\u0026#34; to VOICE_BUBBLE_CHANNELS set:\\n- Before: [\\u0026#34;telegram\\u0026#34;, \\u0026#34;feishu\\u0026#34;, \\u0026#34;whatsapp\\u0026#34;]\\n- After: [\\u0026#34;telegram\\u0026#34;, \\u0026#34;feishu\\u0026#34;, \\u0026#34;whatsapp\\u0026#34;, \\u0026#34;matrix\\u0026#34;]\\n\\n## Test plan\\n\\n- [ ] Send voice message to bot on Matrix (Element)\\n- [ ] Verify TTS reply is sent as MSC3245 voice bubble, not generic file attachment\\n- [ ] Verify waveform, duration, and inline playback metadata present\\n\\nFixes #37061\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/37080\",\"user\":{\"login\":\"Matthew19990919\",\"id\":97017241,\"profile_url\":\"https://github.com/Matthew19990919\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/97017241?v=4\"},\"labels\":[\"channel: matrix\",\"size: S\"],\"assignees\":[\"gumadeiras\"],\"head\":{\"ref\":\"fix/matrix-voice-bubble-tts\",\"sha\":\"89ca0355d4c01e422b115cc83a64382b8c917284\",\"repo\":{\"full_name\":\"Matthew19990919/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"fd2b3ed6af9c3ec6ee9e5e0f16410cf286159002\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-06T03:06:45Z\",\"updated_at\":\"2026-03-21T18:36:56Z\",\"closed_at\":\"2026-03-21T18:29:53Z\",\"merged_at\":\"2026-03-21T18:29:53Z\"},{\"number\":50819,\"title\":\"Tests: isolate remaining March 19 unit-fast OOM hotspots\",\"body\":\"## Summary\\n\\nDescribe the problem and fix in 2–5 bullets:\\n\\n- Problem: the March 19, 2026 Linux Node 24 `unit-fast` OOM lane still had two top memory-growth files missing from the scheduler behavior manifest on current `main`: `src/channels/channels-misc.test.ts` and `src/channels/plugins/outbound/slack.sendpayload.test.ts`.\\n- Why it matters: both files were among the top retained-heap contributors in GitHub Actions run `23327237169` / job `67850928311`, so leaving them in the shared `unit-fast` worker risks another worker-lifetime heap climb and OOM.\\n- What changed: add both files to `unit.singletonIsolated` in `test/fixtures/test-parallel.behavior.json` so they run in dedicated forks instead of the shared `unit-fast` lane.\\n- What did NOT change (scope boundary): no production code, test logic, timings manifest, or wrapper logic changed; this PR only adjusts the scheduler manifest.\\n\\n## Change Type (select all)\\n\\n- [x] Bug fix\\n- [ ] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [x] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [ ] Memory / storage\\n- [ ] Integrations\\n- [ ] API / contracts\\n- [ ] UI / DX\\n- [x] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\n- Closes: None\\n- Related: GitHub Actions run `23327237169`, job `67850928311`\\n\\n## User-visible / Behavior Changes\\n\\nNone.\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? (`Yes/No`) No\\n- Secrets/tokens handling changed? (`Yes/No`) No\\n- New/changed network calls? (`Yes/No`) No\\n- Command/tool execution surface changed? (`Yes/No`) No\\n- Data access scope changed? (`Yes/No`) No\\n- If any `Yes`, explain risk + mitigation:\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS 26.2\\n- Runtime/container: Node `v24.13.0`, local workspace\\n- Model/provider: N/A\\n- Integration/channel (if any): N/A\\n- Relevant config (redacted): `OPENCLAW_TEST_MEMORY_TRACE=1`, heap snapshots enabled for targeted diagnosis\\n\\n### Steps\\n\\n1. Inspect the failing CI log from run `23327237169` / job `67850928311` and note the top `unit-fast` memory deltas.\\n2. Reproduce the hotspot shape locally with repeated heap snapshots across the CI hotspot files.\\n3. Compare repeated snapshots from the same worker PID and classify the retained growth.\\n4. Add the still-missing hotspot files to `test/fixtures/test-parallel.behavior.json`.\\n5. Verify the wrapper now emits dedicated singleton lanes for those files.\\n\\n### Expected\\n\\n- `channels-misc` and `slack.sendpayload` no longer run inside the shared `unit-fast` lane.\\n\\n### Actual\\n\\n- Both files now appear as dedicated lanes: `channels-misc-isolated` and `slack.sendpayload-isolated`.\\n\\n## Evidence\\n\\nAttach at least one:\\n\\n- [x] Failing test/log before + passing after\\n- [x] Trace/log snippets\\n- [ ] Screenshot/recording\\n- [x] Perf numbers (if relevant)\\n\\nBefore:\\n\\n| Source | Lane | Result | Peak RSS | Total delta | Top relevant files |\\n| --- | --- | --- | --- | --- | --- |\\n| GitHub Actions run `23327237169` job `67850928311` | `unit-fast` | OOM | `13.36 GiB` | `+12.62 GiB` | `src/channels/channels-misc.test.ts:+412.5 MiB`, `src/channels/plugins/outbound/slack.sendpayload.test.ts:+319.0 MiB` |\\n\\nDiagnosis:\\n\\n- Reproduce command:\\n  ```bash\\n  OPENCLAW_TEST_MEMORY_TRACE=1 \\\\\\n  OPENCLAW_TEST_HEAPSNAPSHOT_INTERVAL_MS=5000 \\\\\\n  OPENCLAW_TEST_HEAPSNAPSHOT_DIR=.tmp/heapsnap-23327237169-r1 \\\\\\n  OPENCLAW_TEST_WORKERS=1 \\\\\\n  OPENCLAW_TEST_SERIAL_GATEWAY=1 \\\\\\n  pnpm test -- \\\\\\n    src/media-understanding/apply.test.ts \\\\\\n    src/node-host/invoke-system-run.test.ts \\\\\\n    src/channels/channels-misc.test.ts \\\\\\n    src/tui/tui.test.ts \\\\\\n    src/channels/plugins/outbound/slack.sendpayload.test.ts \\\\\\n    src/acp/translator.session-rate-limit.test.ts\\n  ```\\n- Compared lane/PID: `unit`, PID `31261`\\n- Snapshot delta finding: retained growth was dominated by Vite SSR transform strings such as `__vite_ssr_exportName__(...)`, which indicates shared-worker transformed-module retention rather than a runtime object leak.\\n\\nAfter:\\n\\n| Check | Result |\\n| --- | --- |\\n| `OPENCLAW_TEST_LIST_LANES=1 node scripts/test-parallel.mjs` | includes `channels-misc-isolated` |\\n| `OPENCLAW_TEST_LIST_LANES=1 node scripts/test-parallel.mjs` | includes `slack.sendpayload-isolated` |\\n| Local wrapper run after `pnpm canvas:a2ui:bundle` | `unit-fast` completed with `code=0`, `peak=3.28 GiB`, `totalDelta=+1.38 GiB` before the run moved on to singleton lanes |\\n\\n## Human Verification (required)\\n\\nWhat you personally verified (not just CI), and how:\\n\\n- Verified scenarios: inspected the failing CI log, reproduced the hotspot cluster with repeated heap snapshots, confirmed transformed-module retention, and verified the new singleton lanes appear in the wrapper.\\n- Edge cases checked: rebased onto current `upstream/main` and resolved overlap with newly added singleton entries so this PR only adds the still-missing files on top of current main.\\n- What you did **not** verify: I did not wait for a complete post-rebase `pnpm test` run to finish every remaining singleton lane after collecting the passing `unit-fast` summary.\\n\\n## Review Conversations\\n\\n- [x] I replied to or resolved every bot review conversation I addressed in this PR.\\n- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.\\n\\nIf a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? (`Yes/No`) Yes\\n- Config/env changes? (`Yes/No`) No\\n- Migration needed? (`Yes/No`) No\\n- If yes, exact upgrade steps:\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: revert this commit or remove the two entries from `test/fixtures/test-parallel.behavior.json`.\\n- Files/config to restore: `test/fixtures/test-parallel.behavior.json`\\n- Known bad symptoms reviewers should watch for: slightly longer overall test runtime from two additional singleton lanes.\\n\\n## Risks and Mitigations\\n\\nList only real risks for this PR. Add/remove entries as needed. If none, write `None`.\\n\\n- Risk: isolating two more files can modestly increase end-to-end suite time.\\n  - Mitigation: the change is narrowly scoped to the two CI-proven hotspot files that were still missing from the manifest.\\n\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/50819\",\"user\":{\"login\":\"huntharo\",\"id\":5617868,\"profile_url\":\"https://github.com/huntharo\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\"},\"labels\":[\"app: web-ui\",\"scripts\",\"maintainer\",\"size: L\"],\"head\":{\"ref\":\"codex/fix-unit-fast-oom-23327237169\",\"sha\":\"bf218ae75de2f5a1b7d7c6aad26e117532fa5deb\",\"repo\":{\"full_name\":\"huntharo/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"991eb2ef034fea1d6be52733d159a482aa0582af\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T03:55:35Z\",\"updated_at\":\"2026-03-21T18:30:50Z\",\"closed_at\":\"2026-03-21T18:30:50Z\"},{\"number\":51260,\"title\":\"Fix Discord `/codex_resume` picker expiration\",\"body\":\"## Summary\\n\\nDescribe the problem and fix in 2–5 bullets:\\n\\n- Problem: Discord `/codex_resume` picker buttons could immediately fail with `This component has expired.` even though the picker message had just been sent.\\n- Why it matters: resume-by-picker worked in Telegram but was broken in Discord, including the thread-in-channel-in-server flow used for real Codex resume.\\n- What changed: I kept the Discord fallback path from discarding explicit callback payloads, and I moved the Discord component registry onto process-global singleton maps so senders and listeners share the same component state across duplicate module instances.\\n- What did NOT change (scope boundary): I did not change the Codex app server picker generation logic; it was already emitting the expected `codexapp:` callbacks.\\n\\n## Change Type (select all)\\n\\n- [x] Bug fix\\n- [ ] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [ ] Memory / storage\\n- [x] Integrations\\n- [ ] API / contracts\\n- [x] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\n- Closes #\\n- Related #\\n\\n## User-visible / Behavior Changes\\n\\nDiscord Codex resume pickers now stay clickable and can successfully resume a session instead of immediately showing `This component has expired.`\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? (`No`)\\n- Secrets/tokens handling changed? (`No`)\\n- New/changed network calls? (`No`)\\n- Command/tool execution surface changed? (`No`)\\n- Data access scope changed? (`No`)\\n- If any `Yes`, explain risk + mitigation:\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: local dev checkout\\n- Model/provider: Codex app server integration\\n- Integration/channel (if any): Discord thread inside a channel inside a server\\n- Relevant config (redacted): Discord slash command flow with `/codex_resume`\\n\\n### Steps\\n\\n1. Run `/codex_resume` in a Discord thread.\\n2. Click `Browse Projects` or one of the recent-session buttons from the picker.\\n3. Repeat the interaction in the same Discord conversation.\\n\\n### Expected\\n\\n- The picker action is accepted and the selected Codex session view continues normally.\\n\\n### Actual\\n\\n- Before this fix, Discord responded with `This component has expired.` immediately after clicking the picker button.\\n\\n## Evidence\\n\\nAttach at least one:\\n\\n- [x] Failing test/log before + passing after\\n- [x] Trace/log snippets\\n- [x] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\n## Human Verification (required)\\n\\nWhat you personally verified (not just CI), and how:\\n\\n- Verified scenarios: I verified the Discord end-to-end `/codex_resume` flow, including clicking the picker in a Discord thread and successfully resuming a session.\\n- Edge cases checked: I also verified the focused Discord component tests covering callback fallback behavior and duplicate-module registry sharing.\\n- What you did **not** verify: I did not run the full `pnpm test` suite.\\n\\n## Review Conversations\\n\\n- [ ] I replied to or resolved every bot review conversation I addressed in this PR.\\n- [x] I left unresolved only the conversations that still need reviewer or maintainer judgment.\\n\\nIf a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? (`Yes`)\\n- Config/env changes? (`No`)\\n- Migration needed? (`No`)\\n- If yes, exact upgrade steps:\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: revert the two Discord component commits on this branch\\n- Files/config to restore: `extensions/discord/src/components-registry.ts`, `extensions/discord/src/monitor/agent-components.ts`\\n- Known bad symptoms reviewers should watch for: Discord component clicks failing to resolve, or plugin-owned pickers regressing to immediate `expired` responses\\n\\n## Risks and Mitigations\\n\\nList only real risks for this PR. Add/remove entries as needed. If none, write `None`.\\n\\n- Risk: sharing the registry globally could make stale component state survive duplicate module loads longer than before.\\n- Mitigation: the existing TTL and explicit clear/consume paths are unchanged, and I added a regression test for cross-module sharing.\\n\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51260\",\"user\":{\"login\":\"huntharo\",\"id\":5617868,\"profile_url\":\"https://github.com/huntharo\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5617868?v=4\"},\"labels\":[\"channel: discord\",\"scripts\",\"maintainer\",\"size: L\"],\"assignees\":[\"huntharo\"],\"head\":{\"ref\":\"codex/fix-browse-projects-crash-discord\",\"sha\":\"76eb184dbe60cb1c05db02aab426a67b95095cc3\",\"repo\":{\"full_name\":\"huntharo/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"f4227e2787f3b85385f17e7d23decadd8575d478\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T20:30:04Z\",\"updated_at\":\"2026-03-21T18:30:22Z\",\"closed_at\":\"2026-03-21T16:59:22Z\",\"merged_at\":\"2026-03-21T16:59:21Z\"},{\"number\":40126,\"title\":\"feat(memory): pluggable system prompt section for memory plugins\",\"body\":\"## Summary\\n\\n- Problem: The system prompt \\u0026#34;Memory Recall\\u0026#34; section is hardcoded in `system-prompt.ts`, providing memory-core-specific instructions. When a third-party memory plugin is active (via the exclusive memory slot), these instructions are misleading.\\n- Why it matters: Third-party memory plugins need to provide their own system prompt guidance for their tools instead of the hardcoded memory-core instructions.\\n- What changed: Added `registerMemoryPromptSection(builder)` to the plugin API. The active memory plugin registers its own system prompt builder callback. Moved the existing \\u0026#34;Memory Recall\\u0026#34; logic into `memory-core` as its registration. `buildMemorySection()` delegates to the registered callback.\\n- What did NOT change (scope boundary): Default behavior is identical — memory-core registers the same prompt content. No changes to memory tools, compaction, or other plugin APIs.\\n\\n## Change Type (select all)\\n\\n- [ ] Bug fix\\n- [x] Feature\\n- [ ] Refactor\\n- [ ] Docs\\n- [ ] Security hardening\\n- [ ] Chore/infra\\n\\n## Scope (select all touched areas)\\n\\n- [ ] Gateway / orchestration\\n- [ ] Skills / tool execution\\n- [ ] Auth / tokens\\n- [x] Memory / storage\\n- [ ] Integrations\\n- [x] API / contracts\\n- [ ] UI / DX\\n- [ ] CI/CD / infra\\n\\n## Linked Issue/PR\\n\\nNone\\n\\n## User-visible / Behavior Changes\\n\\nNone for default memory-core users. Memory plugins with `kind: \\u0026#34;memory\\u0026#34;` can now register a custom system prompt section via `api.registerMemoryPromptSection(builder)`.\\n\\n## Security Impact (required)\\n\\n- New permissions/capabilities? No\\n- Secrets/tokens handling changed? No\\n- New/changed network calls? No\\n- Command/tool execution surface changed? No\\n- Data access scope changed? No\\n\\n## Repro + Verification\\n\\n### Environment\\n\\n- OS: macOS\\n- Runtime/container: Bun\\n- Model/provider: N/A (system prompt wiring)\\n- Integration/channel (if any): Telegram (for human test)\\n\\n### Steps\\n\\n1. Install a memory plugin that calls `api.registerMemoryPromptSection(builder)`\\n2. Start a session\\n3. Observe that the system prompt contains the plugin\\u0026#39;s memory section instead of the hardcoded one\\n\\n### Expected\\n\\n- With memory-core (default): system prompt contains \\u0026#34;Memory Recall\\u0026#34; section as before\\n- With custom memory plugin: system prompt contains the plugin\\u0026#39;s custom section\\n- With no memory plugin: memory section is omitted\\n\\n### Actual (before fix)\\n\\n- Hardcoded \\u0026#34;Memory Recall\\u0026#34; section always present regardless of active memory plugin\\n\\n## Evidence\\n\\n- [x] Failing test/log before + passing after\\n- [ ] Trace/log snippets\\n- [ ] Screenshot/recording\\n- [ ] Perf numbers (if relevant)\\n\\nNew unit tests in `prompt-section.test.ts`: delegation, citationsMode passthrough, no-builder returns empty, last-registration-wins. All 43 existing `system-prompt.test.ts` tests pass.\\n\\n## Human Verification (required)\\n\\n- Verified scenarios: Tested on two separate OpenClaw bots (Telegram) with memory-core active — memory instructions present as expected, no regression observed\\n- Edge cases checked: None\\n- What you did **not** verify: No memory plugin active (section omitted), custom third-party memory plugin providing its own section\\n\\n## Compatibility / Migration\\n\\n- Backward compatible? Yes\\n- Config/env changes? No\\n- Migration needed? No\\n\\n## Failure Recovery (if this breaks)\\n\\n- How to disable/revert this change quickly: Revert the commit; hardcoded prompt returns\\n- Files/config to restore: N/A\\n- Known bad symptoms reviewers should watch for: Missing \\u0026#34;Memory Recall\\u0026#34; section in system prompt when memory-core is active\\n\\n## Risks and Mitigations\\n\\nNone. Additive API change. Default behavior is identical — memory-core registers the same prompt content it previously hardcoded.\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/40126\",\"user\":{\"login\":\"jarimustonen\",\"id\":1272053,\"profile_url\":\"https://github.com/jarimustonen\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/1272053?v=4\"},\"labels\":[\"extensions: lobster\",\"extensions: memory-core\",\"cli\",\"scripts\",\"agents\",\"size: M\"],\"assignees\":[\"jalehman\"],\"head\":{\"ref\":\"feat/memory-prompt-section-plugin-api\",\"sha\":\"5228d1937f037172762fa64b0f8749403f9ae85f\",\"repo\":{\"full_name\":\"jarimustonen/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"ebfc5f82408f0d592e45db62c61c4834d2cb07e6\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-08T17:38:46Z\",\"updated_at\":\"2026-03-21T18:20:45Z\",\"closed_at\":\"2026-03-21T18:20:45Z\",\"merged_at\":\"2026-03-21T18:20:45Z\"},{\"number\":51146,\"title\":\"fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux)\",\"body\":\"## Summary\\n\\n- Detect nvm-installed Node.js on Linux (via `NVM_DIR` env var or `process.execPath` containing `/.nvm/`)\\n- Auto-set `NODE_EXTRA_CA_CERTS` to the system CA bundle in the systemd service environment when nvm is detected on Linux (same pattern as the existing macOS default)\\n- Probe multiple distro-specific CA bundle paths (`/etc/ssl/certs/ca-certificates.crt` for Debian/Ubuntu/Alpine, `/etc/pki/tls/certs/ca-bundle.crt` for RHEL/Fedora/CentOS, `/etc/ssl/ca-bundle.pem` for openSUSE) — returns `undefined` when none exists, so `NODE_EXTRA_CA_CERTS` is never set to a missing path\\n- Write `NODE_EXTRA_CA_CERTS` to `~/.openclaw/.env` during `openclaw gateway install` so manual `gateway run` also picks up the system CA bundle via dotenv\\n- Backfill `.env` on the `already-installed` path so upgrading users get the entry without `--force`\\n- Injectable `platform`/`execPath` params throughout for testability\\n- Add documentation for nvm/VPS users with the manual workaround\\n\\nFixes #49088\\n\\n## Test plan\\n\\n- [x] `isNvmNode()` unit tests: NVM_DIR env detection, execPath detection, negative cases\\n- [x] `resolveLinuxSystemCaBundle()` probes multiple distro paths, returns undefined when none exists\\n- [x] Service env tests: NODE_EXTRA_CA_CERTS defaults on Linux with/without nvm, user override respected\\n- [x] `execPath` injectable in both `buildServiceEnvironment` and `buildNodeServiceEnvironment`\\n- [x] All 65 service-env tests pass\\n- [x] TypeScript typecheck passes (0 errors)\\n- [x] Lint/format passes\",\"state\":\"closed\",\"draft\":false,\"merged\":false,\"html_url\":\"https://github.com/openclaw/openclaw/pull/51146\",\"user\":{\"login\":\"GodsBoy\",\"id\":5792287,\"profile_url\":\"https://github.com/GodsBoy\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/5792287?v=4\"},\"labels\":[\"docs\",\"gateway\",\"cli\",\"size: L\"],\"head\":{\"ref\":\"fix/nvm-node-extra-ca-certs-v2\",\"sha\":\"2e6cf19c0f91e52e10e0c77b50b85d477f1594f7\",\"repo\":{\"full_name\":\"GodsBoy/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"base\":{\"ref\":\"main\",\"sha\":\"d6367c2c55a2ef40f189300862d022b0276cc017\",\"repo\":{\"full_name\":\"openclaw/openclaw\",\"description\":\"Your own personal AI assistant. Any OS. Any Platform. The lobster way. 🦞 \"}},\"created_at\":\"2026-03-20T16:54:00Z\",\"updated_at\":\"2026-03-21T18:07:18Z\",\"closed_at\":\"2026-03-21T18:06:32Z\",\"merged_at\":\"2026-03-21T18:06:32Z\"}]"}]}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01CEt928fGF79Q1dotPP14HK","type":"message","role":"assistant","content":[{"type":"thinking","thinking":"Now I have all the information. Let me filter for actually merged PRs from the closed PRs list.\n\nLooking at the closed PRs, let me check which ones have `merged_at` set (not null/undefined):\n\n1. PR #51833 - merged: false - NOT merged (closed without merge)\n2. PR #51831 - merged: false - NOT merged\n3. PR #34222 - merged_at: \"2026-03-21T19:06:26Z\" - MERGED ✓ by lml2468\n4. PR #51784 - merged: false - NOT merged (closed without merge)\n\n\n5. PR #51200 - merged: false - NOT merged (closed)\n6. PR #37080 - merged_at: \"2026-03-21T18:29:53Z\" - MERGED ✓ by Matthew19990919\n7. PR #50819 - merged: false - NOT merged (closed)\n8. PR #51260 - merged_at: \"2026-03-21T16:59:21Z\" - MERGED ✓ by huntharo\n9. PR #40126 - merged_at: \"2026-03-21T18:20:45Z\" - MERGED ✓ by ja\n\nNow I'm looking at the most recent merges sorted by timestamp, with the top ones being a memory dedup fix, a TTS voice bubble channels update, and a memory system prompt feature.","signature":"EpMNCkYICxgCKkAg5+Hlt7p4OCu2FLqxpqsh+VSgNux90NokAf5CKEfseZ81vpOlg0Uv9YDgvj0qDL0jteSJQIiq8p6s7TcFB8dkEgw5IK2o5OTKSp3/fZgaDMgHKyt/lY70qxDuQiIwoGCrRzfcPANYodBDi2droQBih5Vxnc3i5NSKfIm0QIyWfOTUPWPSuEOT7mnRqJaMKvoLruC9BQNFXb+227TU/IeUD43Xei2Rl2nBWW26V5i7ovImi+tl7yCXhD+OjzUmT4cW3qoei3c/ZqruTW+Dh3c+Qat64PBA9/vzKTQqWx1ozLCUM+Sgzg8ql6qBKrpreOct6yWZrQ+HCOly/GEjjO59L3oB7z2sdTBzq+OARfiiWegzZ3eCkItBeOwd70ZSxZZNY63heCxRLfVWVwLbwHC1Vuglp4DmA0aB9aBaGMhGRkhliQKQVUl8rBGUIzujzGCKw4vvdiS8fFqPTPrqjXKfLvYyWloxPpDSr4Omv19mXKtK9AW9kp5lkS2hO6aQ0JHUJGrB1w+rMG1Q/8SB516cpFj9GZIcdqpjqeJsto3V5jh9OGsA6Kd9d7lNvoWSdD7YnnqO67Awf469wN1MKk/pKfAVuNzD/95YqP4uXq0BSqTxIkMn7MfE0Ini8RmZ6bw6v0M5n45c9fvYn3t5KNtWkeutr9dNCyfVOW6mvZBZnon8wSk/F9cfM5SP+Bzkq1j2s4HQce2fNVXOlLpW560ZURPHYiBGXMOX6M9Lg29IAuZLg32x+njX6QdKQBOLaT7raZODUmlZRMPiF3wTyPyIteZQ+HLF1e6ATHgCBju+ShpG3pKFEmkhn+X40on98fjCfKRGrnYSXZRoRXtMqB0wVoG7zzZUKKbmKDBCaG+vuiN82NQT38rxnKmQ6BC0m60nyoTIgGWBEa2suIXL2aoHBcpPbu+jbOpnXLwn4sC4MtoKYTCnmFeP0X/z4MiUYUcqZKRHTBVtjyU1lHiuXP59eIO1U8qlT6+KffH11QrlrUUfZ69CLeMhAjzQZIlF2/gu2OKjjmGHbCRAG6wMhsJ8qJbl1eYgXt/4oElpLKfNwPDehuhKw53aBdbBrSVCR3io/T9jDZ9rYUCwsRYdzEJRAx5rdQwuXCJ6B63uiMAj4lpha2srMdLxdsIKa5UTgVaxaqEqUOmoFd9Z+o1mtM7b9kND8q67039SMgJJmedYUJ3Bgf/ihn8XGanl4A05NCXLyZTSv6/cCihkjm7jB8CHe6ZGITaqlkzp7rqFnuwiXq7Qu0CDlqObO4pdmLPWAcdunSZY/gLCfqi96/rdrfoz7CXNRBrjObbkW9nSUsNZqQruKvwgrPj2eXiZb2xOSBCBPjHcfmK4ysKPB0tZuqKN7bFDZ9JRKb5bPMLSkxJH/Aosuqzc7QSskQq6JxTOAlyv7KsCncnlq08g0d8+IVkOjqR9NTjF+9nWkw9ewOpF2JFYWweSr32S/LnsXCmOuX9iipMNwbZWSj3TuHIIO8BrnrEViD9JFL53JDYH1dXvr8DKmVIpEaqEge8KTSLyo1LWLdok1WuXOUFZUu/Zb/rv6Yl0rwy8Utog8s+eG2EK7AWjWstvnXwi1Io2g3xW5gHeCToryIsvsJvN/tG3DN908WBThUPiof6x6G8nOTeE4rME5mle/QtPm9zYtmaw/jJ+lJ+okv9u++Gk4guqp5K4a1pMh40ag+U8x6hbrmVsmVqPHTH8AHVoA1d4SAofpiZNei4q2fMuBaSiYMiWPTQsmio6KUhrFG6eMHQQXm9LWm3IqNC69HII6mTl3phYg/sBV0l5M4VHYfQeqtwGIYkrd791Null2zCbQWU41OJ8+hezxQuocnncbhPMPbU+6XrEntaULwvznjCftjoIn9TcvTwwt2M6VwNpj+xY3mu7XWi9mEp5FXVjXQzyA547QRZsSlJRBSxEtJtXWhwf7jh8kS8UT/zOVOj3wmWaQUVwJOMYS9X+Q8N4yPj01X3rsSmRjZT5OA89atOVp12W/EgXDn5Q3GaxtXB9p6fU2cwLOLXWNX2UIxdZA+k6RMHHnNIlopaJMfPVaPdyuhn0UmVfmZDlep8ntsVIFeMs6I/pd/pwEWcYiOu/sH4rX4mPheIQgsLCMoA5p7lv5h3SVgthDl5ZuKpEGRR2QOiVFIcd03do5xe9c+QWt3C+bQhfunlQm+hl6amWYHGg2tvro+E3TJI33xlZPT41yJKpOcIKxReS2DQuhNtO1/Y+GAE="}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":4181,"cache_creation_input_tokens":12523,"cache_read_input_tokens":17435,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":12523},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"6128d00f-df4a-4c1b-b562-379532e9b99e"}
{"type":"assistant","message":{"model":"claude-sonnet-4-6","id":"msg_01CEt928fGF79Q1dotPP14HK","type":"message","role":"assistant","content":[{"type":"text","text":"Here's your catchup for **openclaw/openclaw**:\n\n---\n\n**Open Issues:** 8,780\n\n---\n\n**5 Most Recently Merged PRs** (all today, 2026-03-21):\n\n| # | Title | Author |\n|---|-------|--------|\n| #34222 | fix: use content hash for memory flush dedup instead of compactionCount | @lml2468 |\n| #37080 | fix(tts): add matrix to VOICE_BUBBLE_CHANNELS | @Matthew19990919 |\n| #40126 | feat(memory): pluggable system prompt section for memory plugins | @jarimustonen |\n| #51146 | fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux) | @GodsBoy |\n| #51260 | Fix Discord `/codex_resume` picker expiration | @huntharo |\n\n---\n\n**Latest Release:** `v2026.3.13-1` — *openclaw 2026.3.13* (published 2026-03-14)\n\n> Note: The `-1` suffix is a recovery tag only (the GitHub release for `v2026.3.13` was immutable after publication); the npm package version is still `2026.3.13`."}],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":4181,"cache_creation_input_tokens":12523,"cache_read_input_tokens":17435,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":12523},"output_tokens":8,"service_tier":"standard","inference_geo":"not_available"},"context_management":null},"parent_tool_use_id":null,"session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","uuid":"1aefd8d0-bbc7-495e-83e2-f51d8f9b8bbc"}
{"type":"result","subtype":"success","is_error":false,"duration_ms":24357,"duration_api_ms":23729,"num_turns":5,"result":"Here's your catchup for **openclaw/openclaw**:\n\n---\n\n**Open Issues:** 8,780\n\n---\n\n**5 Most Recently Merged PRs** (all today, 2026-03-21):\n\n| # | Title | Author |\n|---|-------|--------|\n| #34222 | fix: use content hash for memory flush dedup instead of compactionCount | @lml2468 |\n| #37080 | fix(tts): add matrix to VOICE_BUBBLE_CHANNELS | @Matthew19990919 |\n| #40126 | feat(memory): pluggable system prompt section for memory plugins | @jarimustonen |\n| #51146 | fix(install): auto-write NODE_EXTRA_CA_CERTS to .env on nvm Node.js installs (Linux) | @GodsBoy |\n| #51260 | Fix Discord `/codex_resume` picker expiration | @huntharo |\n\n---\n\n**Latest Release:** `v2026.3.13-1` — *openclaw 2026.3.13* (published 2026-03-14)\n\n> Note: The `-1` suffix is a recovery tag only (the GitHub release for `v2026.3.13` was immutable after publication); the npm package version is still `2026.3.13`.","stop_reason":"end_turn","session_id":"56aea5b8-5a76-4f9a-836d-c390326c1b2b","total_cost_usd":0.1270761,"usage":{"input_tokens":4187,"cache_creation_input_tokens":21360,"cache_read_input_tokens":42467,"output_tokens":1445,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":21360,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{"claude-sonnet-4-6":{"inputTokens":4187,"outputTokens":1445,"cacheReadInputTokens":42467,"cacheCreationInputTokens":21360,"webSearchRequests":0,"costUSD":0.1270761,"contextWindow":200000,"maxOutputTokens":32000}},"permission_denials":[],"fast_mode_state":"off","uuid":"0dcf0a20-c8bd-47c0-ad35-6994e293347c"}
