Preserve structured tool-result replay text across provider transports while keeping provider-facing redaction and Anthropic media ordering intact.
Thanks @snowzlmbot!
* feat(openai): add GPT-5.6 series support
* docs: refresh map for GPT-5.6
* fix(openai): preserve GPT-5.6 thinking metadata
* fix(codex): sync managed app server version
* fix(codex): sync managed app server version
* fix(openai): account for GPT-5.6 cache writes
---------
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
* feat(ios): refine control and talk visual hierarchy
* feat(ios): refine control and talk visual hierarchy
* feat(ios): refine control and talk visual hierarchy
* fix(cli): explain how to recover from device approve deadlock
`openclaw devices approve` could fail two ways with no path forward:
- When the calling device can't approve its own scope upgrade (it lacks
operator.approvals) and no loopback local fallback is available (e.g. a
remote --url gateway), the raw "scope upgrade pending approval" error
propagated with no guidance.
- When the request id wasn't found in pending state (already approved,
expired, or superseded), it printed only "unknown requestId".
Surface actionable guidance instead:
- On an authorization failure, explain that the device can't approve its
own upgrade and point to `--token`/`--password` (gateway owner creds) or
approving from a device that already holds operator.approvals.
- On a missing request, point to `openclaw devices list` and
`openclaw devices approve --latest`.
AI-assisted (Claude Code).
* fix(cli): clarify device approval recovery
* fix(cli): avoid unusable approval credential advice
Summary:
- The branch adds bundled skill-creator guidance to route durable OpenClaw skill work through Skill Workshop proposals and removes the direct `init_skill.py` scaffold helper plus its test.
- PR surface: Docs +6, Other -429. Total -423 across 3 files.
- Reproducibility: yes. source-level: current main has `init_skill.py` writing a live `SKILL.md` directly, whi ... `. I did not run the direct helper as a repro because this review was read-only and that path writes files.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 8eca165447.
- Required merge gates passed before the squash merge.
Prepared head SHA: 8eca165447
Review: https://github.com/openclaw/openclaw/pull/98346#issuecomment-4849855806
Co-authored-by: momothemage <niuzhengnan@163.com>
Approved-by: momothemage
The in-loop context-overflow guard (installToolResultContextGuard) sizes
transcript messages via estimateMessageChars, which only handled user,
assistant, and toolResult roles. Harness roles (bashExecution,
compactionSummary, branchSummary, custom) fell through to a flat 256-char
return, causing the guard to undercount summary- and bash-dominated
context by orders of magnitude.
This is the sibling defect of the just-merged #97861 which fixed the same
class in estimateMessageTokenPressure (the pre-prompt precheck). This
commit applies the identical pattern to the live in-loop guard estimator.
Fixes#97927
matchLevelDirective consumed the token after a level directive
(/think, /verbose, /trace, /fast, /reasoning, /elevated) as the level
argument unconditionally, and extractLevelDirective stripped it from the
body whether or not it was a valid level. So a message like
"/verbose explain quantum computing" reached the agent as
"quantum computing", silently dropping the user's first word, and the
whitespace scan crossed newlines so "/verbose\nSummarize this" lost
"Summarize".
Treat the trailing token as the directive argument only when it
normalizes to a valid level or is the sole remaining token (preserving
the unrecognized-level hint and the default/inherit clear sentinels).
When two or more words follow, the directive acts argument-less and the
message text is preserved intact, matching the exec and queue parsers
that stop at an unrecognized token.
The gateway agent.run freshness decision called evaluateSessionFreshness
directly at both of its decision sites with no provider-owned guard, so a
provider-owned CLI session (claude-cli, codex, gemini-cli) under the default
reset config was rotated after the daily boundary when a turn ran through the
gateway path (webchat, openclaw agent, ACP, control UI, cron, heartbeat). The
rotation cleared the CLI session binding and split the transcript, violating
the documented exemption that the inbound auto-reply path and the canonical
session helper already honor.
Route both gateway freshness decisions through the same
resetPolicy.configured !== true && hasProviderOwnedSession(entry) skip the
inbound path uses, and export hasProviderOwnedSession so the predicate has one
shared definition instead of a third copy. Explicit session.reset and /reset
still cut these sessions.
Summary:
- Merged fix: show in-progress status for channel runs after ClawSweeper review.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 08eec41769.
- Required merge gates passed before the squash merge.
Prepared head SHA: 08eec41769
Review: https://github.com/openclaw/openclaw/pull/98257#issuecomment-4849525931
Co-authored-by: scotthuang <scotthuang@tencent.com>
Approved-by: takhoffman
* fix(agents): keep merged delivery routes account-bound
mergeDeliveryContext gated route-field crossing on channel only, so a
completion origin that knew its account but not a concrete target
inherited a different account's to/threadId on the same channel. A
subagent, cron, or media completion for bot-a could be addressed to
bot-b's chat but sent through bot-a (cross-account misroute) or dropped.
This restores the account-bound guard added in 1ed8592467 and removed as
collateral by 025db6cf9e (PR #89949); same-account and missing-account
merges still backfill so the media route-pin path is preserved. Restores
the deleted regression test.
* fix(agents): centralize account-bound completion routes
---------
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
* 'main' of https://github.com/openclaw/openclaw: (29 commits)
refactor(gateway): trim attach grant implementation
feat(gateway): scoped attach grants for external MCP loopback clients
fix(gateway): iOS Talk treats SecretRef-backed API keys as missing (#98210)
test(infra): add unit tests for SQLite number normalization (#98009)
test(config): add unit tests for resolveExecCommandHighlighting (#98087)
test(utils): add unit tests for chunkItems (#98219)
fix(core): propagate caller env PATHEXT through isExecutableFile on Windows (#98093)
fix(matrix): guard JSON.parse against malformed homeserver response bodies (#97973)
fix(sms): guard Twilio JSON.parse against malformed API response bodies (#97999)
Add Swedish mobile app localization (#98043)
fix(anthropic): surface Discord pre-tool commentary
fix(tui): correct disconnect copy for device scope upgrades (#98144)
chore(ui): refresh fa control ui locale
chore(ui): refresh nl control ui locale
chore(ui): refresh vi control ui locale
chore(ui): refresh th control ui locale
chore(ui): refresh pl control ui locale
chore(ui): refresh uk control ui locale
chore(ui): refresh id control ui locale
chore(ui): refresh tr control ui locale
...
Per-session, TTL-bounded, revocable bearer grants (mcp-grant-store) let an external/interactive
harness reach the gateway's scoped MCP loopback tools without the cli-backend's process-global
token. A grant is a lower-trust boundary: it binds the session server-side AND fail-closes on every
caller-supplied context header (x-session-key plus message-channel/account/current-channel/thread/
source-reply/event-kind), so a grant holder can neither scope-shop the session nor spoof
delivery/action context into scoped tools or the message tool. New attach.grant/attach.revoke
operator methods mint/revoke grants and return the loopback MCP config. Owner/non-owner cli-backend
path unchanged.