Skip to content

[pull] main from openclaw:main - #653

Open
pull[bot] wants to merge 2076 commits into
sanketshah-dev:mainfrom
openclaw:main
Open

[pull] main from openclaw:main#653
pull[bot] wants to merge 2076 commits into
sanketshah-dev:mainfrom
openclaw:main

Conversation

@pull

@pull pull Bot commented Aug 21, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

@pull pull Bot locked and limited conversation to collaborators Aug 21, 2026
@pull pull Bot added the ⤵️ pull label Aug 21, 2026
snotty and others added 26 commits August 26, 2026 14:08
* fix(ai): reconcile rotated Responses output identities

Retain output position, completion, and block ownership in one shared tracker for terminal text recovery and reasoning backfill. Preserve unindexed aliases and reject changed output types or stable tool-call IDs.

Co-authored-by: snotty <snotty@users.noreply.github.com>

* docs: keep Copilot release notes in PR context

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: snotty <snotty@users.noreply.github.com>
)

* refactor(channels): remove private forwarding modules

* refactor(discord): consolidate config type imports
* fix(browser): bound response body reads through completion

* test(browser): use public response test types
Gather and validate each requested camera response before publishing any capture, so a malformed second reply cannot leave the first photo on disk. Reuse photo artifact and result construction for camera snapshots and library photos.

Preserve first-payload validation before requesting another camera. Downloads and filesystem failures retain per-file semantics rather than promising batch rollback.
* fix(gateway): return complete errors after HTTP route failures

* test(gateway): complete HTTP response mock header support
* feat: make model persistence scope explicit

* fix: keep unauthorized model directives as plain text

An unauthorized sender's inline directives are cleared to plain text before
they are acted on, but the persistent write target was derived from the
directives as they arrived. An unauthorized `/model <provider/model> -a` or
`-g` therefore reached the owner-authority error return instead of the
plain-text path every other directive takes.

Derive the target, the authority flag, and the persist flag after the
clearing. Authorized senders skip the clearing, so their behavior is
unchanged; the only closure that captures the target is invoked well after
the new declaration site.

Covers both persistent flags with a regression test that fails on the prior
head with "Agent and global model defaults require owner authority or
operator.admin scope." and passes here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(models): make model selection scope configurable

Preserve current model-selection defaults when the optional scope preference is unset. Add explicit session, agent, and global overrides without broadening config-write authority.

Co-authored-by: Marvinthebored <peter@lindsey.jp>

* test(models): simplify scope expectation fixtures

---------

Co-authored-by: Marvinthebored <peter@lindsey.jp>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* docs: compact generated maturity scorecard rows

* docs: align compact maturity scorecard output
* fix(workers): revalidate idle and node readiness after waits

* test(cli): keep gateway fixture PID distinct from updater
* fix: allow plugin state values up to 1 MiB

* test: type-check plugin state write rejection cases

* fix(ci): keep tar archive paths local on Windows
* perf(ui): collapse session roster bootstrap RPCs

Amp-Thread-ID: https://ampcode.com/threads/T-01a037b3-be95-76ea-8fb3-75979929acf1

* fix(gateway): isolate and bound session roster bootstrap

Scope cached projections to the authenticated viewer, apply startup admission
consistently, and preserve the independent owner and shared preview budgets.
Regenerate the Swift client and document the bootstrap and cursor contract.
Publish Gateway test configuration atomically to remove the deferred-reader race.

Co-authored-by: Amp <amp@ampcode.com>

* test(gateway): extract session roster cache fixtures

---------

Co-authored-by: Amp <amp@ampcode.com>
* refactor(discord): centralize voice resource lifecycle

* test(discord): avoid returning from voice promise executor
…ctured diagnostics, native highlight (#130388)

* fix(macos): stabilize status menu width across hosted and native rows

* fix(macos): format node worker termination status without optionals

* refactor(macos): give status menu width one owner

fittedTitle's hasImage/hasSubmenu/keyEquivalent parameters never changed
the computation - the budget always included image, submenu, and shortcut
chrome - because AppKit aligns those columns across the whole menu, so a
per-item budget is the wrong model. Collapse to one menu-wide budget and
drop the misleading knobs from all 13 call sites.

* refactor(macos): keep the status menu header quiet when healthy

A working system now says nothing: the header renders only operator-
actionable trouble lines (colored text, no status bubbles), the healthy
state is title + toggle + capability strip, and the churn sources that
made the open menu jump are gone - relative check ages, 'health check
running', and the per-tool activity label (the critter icon already
animates work). Session-row kind icons go monochrome; green conveyed
nothing actionable. Healthy title is 'OpenClaw' (or the primary gateway
name with multiple gateways) since the toggle already communicates
active. DashboardGatewayMenuModel.connectionLabel lost its last caller
and is deleted with its test.

* fix(macos): preserve structured node worker diagnostics in status menu

* feat(macos): highlight hosted menu rows from AppKit's selection signal

AppKit paints no selection behind NSMenuItem.view, so hosted session and
device rows had no hover or keyboard highlight. HostedMenuRowView now
draws the native selection material (rounded, emphasized) and flips the
SwiftUI content through the existing menuItemHighlighted environment,
driven by NSMenuDelegate.menu(_:willHighlight:) so pointer and arrow-key
navigation both light up. Submenus get a shared highlight-only delegate;
the controller's root-menu guards keep open/refresh paths unaffected.

* refactor(macos): drop the manual Open Canvas action

Canvas panels are agent-opened; a manual open action was noise. The
Allow Canvas capability tile stays - that is the permission. Removes the
menu action, the dock-menu item, and the now-orphaned
AppNavigationActions.toggleCanvas.

* fix(macos): clear hosted submenu selection when the submenu closes

AppKit sends no willHighlight(nil) on submenu close, so a hosted device
row selected there reopened still lit. The shared highlight delegate now
resets its menu's hosted rows in menuDidClose; regression covers the
close cycle.

* style(macos): apply swiftformat to highlight delegate
* fix(ui): hide unavailable discussion panel

* fix(ui): couple dashboard side panel to split mode
* refactor(models): prepare selection policy once

* style(models): fix selection exports and return consistency
* feat(feishu): resend received stickers without losing topic routing

Add opt-in agent sticker sending using received file keys, preserve inbound keys, and stop unsupported sticker resource downloads. Reuse keyed-media delivery and canonical reply selection; inherit source topics only within the same destination and account. Related: #114578.

* fix(feishu): preserve topic mode for prepared implicit replies

* docs(feishu): preserve account action gates when enabling stickers
)

* fix(ui): distinguish inherited model defaults from session pins

The Gateway session projection collapsed inherited agent defaults and
persisted conversation pins into the same effective model fields, so the
Control UI picker marked a row Default while its footer simultaneously
called it a session override and offered a meaningless reset.

Project the authoritative persisted provenance instead: the session owner
resolves `modelOverrideSource` (normalizing entries written before source
tracking), `buildGatewaySessionRow` and the session change event carry the
additive `"user" | "auto" | null` protocol field, and the Control UI treats
only `"user"` as a conversation pin.

Closes #120752

* test(ui): scope model provenance to active pane

* fix(ui): derive the model picker's inherited sentinel from recorded provenance

Deriving "inherits the agent default" from the effective model matching the
default meant a session pinned to model X stopped reading as pinned once the
agent default moved to X. The picker then rendered the default row as already
selected, so clicking it matched its own commit value and was swallowed, leaving
the stored pin unreachable from the UI.

Project the session store's existing modelOverrideSource onto the gateway row and
let the UI resolve a closed selection source (inherited/pinned/fallback) from it,
falling back to the old equality guess only for gateways too old to send the
marker. Preserve the null tombstone in reconcile so a cleared pin stays
distinguishable from that silence.

* test(ui): pin the model picker's digit-key ownership

The numbered keycaps and the digit handler are paired by search focus, but the
guard that keeps digits in the search input had no coverage outside the browser
e2e lane. Add a unit regression for both halves and record the contract at the
numbering site, where reviewers keep reading the two gates as unrelated.

* fix(ui): keep session model selection provenance authoritative

Project saved model provenance through Gateway rows and events, retire temporary UI claims at their owner, and use canonical refresh after slash and status model changes. Preserve model intent through rollback and deletion without retaining a public cache setter.

Co-authored-by: Vyctor H. Brzezowski <krzyszchweski@gmail.com>

* refactor(ui): keep recovery with scoped session operations

Preserve recovery notifications, visible errors, and connection checks while keeping the optimistic mutation owner within its module limit.

Co-authored-by: Vyctor H. Brzezowski <krzyszchweski@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Dashboard tools now stay bound to the Gateway that admitted the agent run. Reads, mutations, and broadcasts fail closed if that Gateway is replaced or retired instead of transferring authority to another instance.
A Crabbox cloud-worker setup failure could report none of the reason it
failed. crabboxCommandDetail kept the first ~254 and last ~253 characters
and dropped the middle, but Crabbox always prints a fixed ~250-character
run-context banner first, so head preservation spent half the budget on
boilerplate. In a live machine0 failure the actionable line sat at
collapsed index 2570 and was deleted; the operator saw a banner and a
Node stack tail that read like a workspace-lock problem.

Keep the tail instead: a failing command's diagnosis is last, and the
capture layer in src/process/exec-output.ts already retains each stream's
suffix. Join [stdout, stderr] so stderr occupies the retained window
rather than being pushed out by a chatty stdout. The 512-character budget
is unchanged and stays inside core's 1024-unit bound.

Profile, desktop, and node enrollment setup also all failed as
"Crabbox setup failed", so the message never said which phase broke.
Each now carries its own label, matching the shared SSH bootstrap in
src/gateway/worker-environments/bootstrap.ts.

Net -4 production lines.
* fix(qa): honor pooled Buzz credentials in profiles

* test(qa): guard optional Buzz cleanup

* fix(qa): delegate Buzz profile credential selection

* refactor(qa): simplify Buzz source handoff

* docs(qa): clarify Buzz credential delegation
* fix(ui): clarify disconnected gateway title

* fix(ui): keep disconnect title concise

* test(ui): align shell disconnect title
edenfunf and others added 30 commits August 27, 2026 10:53
Keep official plugins on the gateway release stream so beta gateways do not silently install stable artifacts. Resolve hosted catalog entries at the shared boundary, stop missing cohorts before hook fallback, and keep recovery notices visible.

Co-authored-by: 許元豪 <146086744+edenfunf@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
…29255)

* fix(tasks): detect sentence boundaries without space after terminator

hasNonProgressFollowupSentence only recognized a sentence boundary when
the terminator was followed by whitespace. Glued ACP outputs (e.g.
"...behavior.There's no unit-test target yet...") never matched, so a
complete final report following progress narration was classified as
progress-only and the required completion was reported as blocked.

Insert the missing space after [.!?:] when followed directly by an
uppercase letter before running boundary detection, and add regression
tests.

Closes #129222

* fix(tasks): exclude structured colon tokens from sentence-boundary normalization

* fix(tasks): keep dotted references glued in sentence-boundary normalization

The uppercase lookahead normalization inserted a space after any dot
followed by an uppercase letter, which fabricated sentence boundaries
inside dotted structured references. "I'll inspect API.Client" became
"I'll inspect API. Client": the first fragment matched the progress
prefix and "Client" was treated as a final deliverable, turning a
blocked progress-only result into a false completed verdict.

Skip the space insertion when the dot sits inside a dotted
identifier/path token (identifier chars around the dot, no whitespace
in the token) or is followed by a known file extension (Kt, py, js,
ts, json, yaml, toml, sh, mjs, cjs, go, rs, java, cs, h, cpp). Real
glued sentence boundaries ("repo.There's...") still get the space and
are still split. Add regressions for API.Client, foo.Bar and
src/main.Kt / config.py, which are red on the pre-fix head and green
now.

* fix(tasks): recognize glued prose before dotted-reference exemptions

The whole-token dotted-reference exemption also preserved glued prose
boundaries such as hooks.Targets and suite.PinPoints from the reported
#129222 transcript, so their missing spaces were never inserted and the
contract only reached a completed result incidentally via a later spaced
boundary.

insertMissingSentenceSpaces now splits a dot glued to a Capitalized word
after a lowercase word when the continuation starts a sentence, and keeps
glued only structured dotted references: known extensions, paths, acronyms,
multi-dot tokens, and camelCase identifiers followed by planning narration
or punctuation. The normalizer is exported and asserted directly in tests,
and punctuated dotted references (API.Client,) stay progress-only.

* fix(tasks): preserve ordinary dotted progress references; privatize normalizer

* fix(tasks): recognize glued prose boundaries before ordinary-continuation exemption

The lowercase-continuation exemption from the previous round treated
every plain post-dot word followed by lowercase text as a structured
dotted token, which also swallowed the reported glued prose boundaries
(issue #129222): 'hooks.Targets are wired' and 'suite.PinPoints now has'
were left glued, so a report whose only boundary is one of these stayed
progress-only and blocked.

Only clause-opening continuations now split: copulas/auxiliaries, or the
sentence adverb 'now' before a finite verb. Ordinary noun-phrase
continuations ('foo.Bar results') still keep the dotted reference glued,
so progress narration is never split into a fake deliverable.

* fix(tasks): recognize general now+finite-verb glued prose boundaries (#129222)

Generalize the now-branch of the sentence-opening continuation pattern
from a closed auxiliary/copula whitelist to any finite verb that is not
a closed-class function word, so reports like 'suite.PinPoints now
works.' split at the glued boundary instead of being misread as a final
deliverable. Regression tests for general and inflected finite verbs
(red -> green).

* fix(acp): classify complete task output before truncation

Co-authored-by: Finn763 <165816600+Finn763@users.noreply.github.com>

* fix(acp): count joined completion evidence bytes

Co-authored-by: Finn763 <165816600+Finn763@users.noreply.github.com>

---------

Co-authored-by: Finn763 <Finn763@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(codex): update managed runtime to 0.150.1

* test(codex): refresh newer runtime fixtures
…30701)

* fix(codex): prevent stale resumes from disrupting shared sessions

Carry the existing ownership assertion to each physical RPC write and overload retry. Clear request uncertainty after an explicit overload rejection so a revoked retry preserves its healthy shared client. Remove the redundant request forwarding method.

Verified with transport regressions, 318 focused tests, lint, formatting, and independent review. Live Gateway verification follows before landing.

* docs: keep resume fix release notes in the PR body
* refactor: simplify channel config adapters

* refactor(ui): share session-default reading
* fix(pr): release locks after linked worktree teardown

* test(pr): verify native cleanup and retained lock ownership

Initialize the existing script-local supervisor root before canonical Git resolution, and replace overlapping teardown fixtures with the real native merge and gc lifecycle.

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Resolve attachment MIME aliases once and carry normalized metadata through send preservation and structured hydration. Remove stale nested-MIME publication while preserving filenames, sniffing and staging. Closes #130711.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
…30704)

* fix(doctor): stop flagging lazily-created session dirs as missing

* test(doctor): split state-integrity suite to satisfy max-lines
* docs(start): add Why OpenClaw enterprise architecture page

Source-audited architecture argument for enterprise evaluators: trusted
gateway vs movable untrusted execution, policy-as-code, tiered access,
SecretRef chain, versioned state, provenance, open standards, and a
commit-pinned comparison with Hermes Agent verified against both source
trees. Registers the page in the Get started nav and fixes the OpenShell
policy config description (YAML path, not ID).

* docs(start): link landed feature pages and split the Hermes verdict paragraph

* docs(start): state the comparison in present tense

* docs(start): tighten register after external language review

* docs(start): address review findings

Restore main's OpenShell guide unchanged (rebase resolution had
resurrected the pre-rewrite page), defer the plugin consent screen
claim until its implementation merges, scope the memory forget claim
to tracked artifacts of selected sessions, replace brittle RPC and
capability counts, state OpenAI-compatible API limits, and add
immutable permalinks for every external Hermes citation.
Keep Tlon Urbit event delivery and acknowledgements working when legal SSE data and id fields omit the optional space.

Parse both fields at the Tlon-owned boundary and retain focused parser plus loopback transport proof.

Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>
Co-authored-by: nebulacoder-v8.0 <noreply@zte.com.cn>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
…es (#130134)

Propagate transient Signal approval-reaction failures so durable ingress releases and replays the claim instead of silently completing it. Preserve expired-approval cleanup and the real SQLite owner-boundary regression.

Fixes #130133.

Co-authored-by: wangmiao0668000666 <wang.miao86@xydigit.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix: avoid stalled maintainer author activity lookups

* test: validate required author activity fixture entries
…6856)

Preserve ordinary paired self-chat delivery past the five-hit loop threshold while retaining real echo and reflected-content protection. Reuse the monitor integration fixture and consolidate equivalent TTL cases; total LOC is net negative.

Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(cli): models refresh rejects parent --agent like set/aliases/scan

`models refresh` refreshes the global hosted catalog
(refreshRemoteModelCatalog) and takes no agent, but silently accepted a
parent --agent, implying a per-agent scope it does not deliver. #126864
landed rejectAgentScopedModelCommand for set/set-image/aliases/scan but
left refresh unaddressed (it scoped out only fallbacks/image-fallbacks).
Add "refresh" to GlobalOnlyModelCommandName and switch refresh's action
to the same loadModelsRuntime + reject + runModelsCommand pattern, so
--agent fails fast with the same error instead of a silent global refresh.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(cli): list models refresh among --agent-rejecting commands

`docs/cli/models.md` listed `set`/`set-image`/`scan`/`aliases` as
rejecting `--agent` but omitted `refresh`, so the new guard landed in
the previous commit was not reflected in the docs. Add `refresh` to the
global-only list and note it on the refresh section.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: ruel225 <ruel225@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Use the latest nonempty function-name snapshot for a resolved tool call so fragmented direct OpenAI-compatible streams do not publish stale tool names. Preserve the first tool identity when a later fragment supplies an explicitly conflicting ID.

Co-authored-by: SunnyShu0925 <shu.zongyu@xydigit.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.