`listChannelCatalogEntries` invoked `discoverOpenClawPlugins` without
forwarding `installRecords`, so npm-installed channel plugins recorded
in `~/.openclaw/plugins/installs.json` were absent from the CLI channel
catalog. `openclaw channels add --channel <id>` and
`openclaw channels login --channel <id>` therefore reported
"Unsupported channel" / "Unknown channel" for any third-party plugin
even when its ledger entry was healthy. Bundled plugins (qqbot, telegram,
etc.) reach the same catalog via the stock discovery path, which is why
they were unaffected.
Lazy-load the persisted ledger via
`loadInstalledPluginIndexInstallRecordsSync` when the caller does not
specify `origin === "bundled"`, and forward the records to discovery.
Bundled-only callers continue to skip the disk read; callers that
already loaded records (e.g. tests, batch flows) can pass them
explicitly. Reader failures fall back silently to "no install records",
preserving prior behaviour.
Also register `@tencent-weixin/openclaw-weixin` in
`scripts/lib/official-external-channel-catalog.json` so the channel
appears in onboarding flows that consult the catalog directly.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(agents): persist embedded runner session transcripts (#77823)
Run persistCliTurnTranscript and post-turn compaction for executionTrace.runner embedded,
matching CLI turns so assistant text reaches session JSONL for webchat/Feishu-style runs.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(agents): narrow embedded transcript mirror with assistant dedupe (#77823)
Embedded runs pass embeddedAssistantGapFill so persistCliTurnTranscript skips
re-appending the user prompt Pi owns and only appends assistant text when the
transcript tail lacks equivalent visible assistant content.
Adds CLI transcript regression coverage for gap-fill dedupe.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(agents): dedupe embedded transcript gap fill by tail
* fix: persist embedded session transcripts (#77839) (thanks @neeravmakwana)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
When directive consume() returned null (e.g. silent NO_REPLY chunk) or the
cleaned payload was empty, we still set lastBlockReplyText, so message_end
skipped the safety send while no channel delivery had occurred.
Fixes#77833.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Harden config backup restore permissions
* docs(changelog): credit config restore mode hardening
Adds the user-facing Unreleased Fixes entry for the suspicious-read backup
restore chmod hardening shipped in this PR.
Add a Fireworks-owned thinking policy for Kimi models so K2.5/K2.6 only expose `off`, keep the bundled provider-policy artifact aligned, and keep request payloads on Fireworks-accepted `thinking: disabled` while stripping rejected `reasoning*` fields.
Refs #74289.