Restore standalone Buzz npm and ClawHub packaging by using the shipped QA runner SDK surface and generated dependency lock workflow.
Prepared head SHA: 58d0a52c61
Co-authored-by: Shakker <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
* fix(imessage): bold approval prompt labels in poll mode
#113193 added bold headers and labels to the approval reaction prompt, but
iMessage only shows that copy when tapbacks own the controls. On any
poll-capable bridge the details message is built from `manualFallbackPayload`,
the legacy unstyled builder, so every label (`Title:`, `Tool:`, `Host:`,
`CWD:`, `Full id:`, ...) reaches Messages as flat text. Native polls are the
default on a bridge-v2 host, so in practice #85954 still reproduced after it
was closed.
Add `nativeControlsPayload` to `ApprovalReactionPendingContent`: the same rich
copy as `reactionPayload` minus the tapback hint, for channels whose native
controls already own the decision surface. iMessage poll mode now renders it,
so both control paths deliver identical styled copy.
`imsg poll send --question` has no attributed-body channel, so the poll
question keeps the marker-free rendering of that same text; otherwise the
balloon would show literal asterisks.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Byq7UrC7ZpMHxoFXcddsa
* refactor(plugin-sdk): carry native-controls prompt copy as text
The iMessage poll path reads exactly one thing from the native-controls
payload: its text. Replace the ReplyPayload field with nativeControlsText so
buildApprovalReactionPendingContent stops running the metadata/session-key
builder for fields no caller reads, and the '?? ""' sentinel goes away.
Relative to main the SDK change stays additive: neither field exists in any
release; nativeControlsPayload only ever existed on this branch.
* refactor(plugin-sdk): expose native-controls prompt text as a builder, not a type field
ClawSweeper flagged that requiring a new member on the shipped
ApprovalReactionPendingContent type is source-incompatible for external
producers that hand-construct it. The hint-free copy does not need to ride
the type at all: export buildApprovalNativeControlsPromptText and let the
iMessage handler call it at payload-build time.
ApprovalReactionPendingContent is now byte-identical to the shipped shape;
the SDK change is a single additive function export. Signal/WhatsApp test
fixtures revert to their original form.
---------
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
A status headline replaced the rolling tool lines instead of sitting above
them, so a default Discord draft showed one preamble sentence for an entire
tool-heavy turn. Operators reached for `/verbose` to see any activity, which
delivers durable per-tool-call messages and floods the channel.
- Render the headline above the lines; both stay visible in one message.
- Shorten the start gate from 5s to 1.5s. The gate only creates the draft
when the timer fires and finalize cancels it, so quick answers still post
no draft while a 3s tool turn stops being silent.
- Drop Discord's label-gated tool-progress default so
resolveChannelStreamingPreviewToolProgress is the single owner. An explicit
`toolProgress: false` still silences the lines.
- Resolve that toggle against a "progress" mode guess when `streaming.mode`
is unset, so the progress-draft channels stop ignoring an explicit
`progress.toolProgress` opt-out.
Telegram now defaults to `streaming.mode: "progress"` like Discord; set
`"partial"` to keep streamed answer text. Its renderer draws work lines from
the compositor's structured lines, so `rendersRollingLinesNatively` keeps
them out of the composed text rather than printing every line twice.
* fix(plugin-sdk): add missing thinking stream hooks to provider-stream-family exports
The provider-stream-family subpath was missing re-exports for deprecated
thinking-stream hook constants (MOONSHOT_THINKING_STREAM_HOOKS,
GOOGLE_THINKING_STREAM_HOOKS, KILOCODE_THINKING_STREAM_HOOKS,
MINIMAX_FAST_MODE_STREAM_HOOKS, OPENROUTER_THINKING_STREAM_HOOKS,
TOOL_STREAM_DEFAULT_ON_HOOKS) that are defined in provider-stream.js.
This caused @openclaw/moonshot-provider to fail at load time with:
SyntaxError: does not provide an export named 'MOONSHOT_THINKING_STREAM_HOOKS'
Fixes#115580
* test(plugin-sdk): preserve provider stream family exports
* test(plugin-sdk): cover provider stream compatibility exports
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Allow before_agent_reply plugins to declare host-enforced trigger eligibility so scheduled-only hooks do not block interrupted user-turn recovery. Keep omitted and malformed scopes fail-closed, scope both memory-core maintenance hooks, and cover three runner reload cycles through the public registration contract.
Refs: #111442
Source: #114836
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Track full dispatch completion separately for error handling and shutdown drain while allowing same-session follow-ups to steer active runs. Fixes#113180.
Co-authored-by: Taksh <takshkothari09@gmail.com>
* fix(telegram): coalesce durable album ingress
Split durable claim lifetime from lane occupancy so Telegram can admit later album members while every deferred claim remains heartbeated, recoverable, and independently settled.
With deferredLaneOccupancy=release, an unrelated later same-lane Telegram message can reach reply admission before an album that is still inside its 500 ms flush window. That restores the pre-f7786a16 contract, not a new defect; grammY sequentialize still preserves handler-entry order and the reply lane serializes once a turn is admitted.
* fix(telegram): preserve deferred abort semantics
Release deferred claims when their owner aborts before settlement, while preserving adoption when settlement won the race. Supersede every accepted pre-adoption state on released lanes without admitting past a surviving lane owner.
* fix(telegram): separate participant rejection from settlement failure
The detached deferred continuation chained its rejection handler with .catch
after .then, so it observed not only a participant.task rejection but also any
error thrown by onFailed()/onAdopted() and re-drove that infrastructure error
through onFailed().
That applied the wrong disposition when the claim was still pre-adoption, and
silently discarded the error once it was not: onAdopted() sets phase to adopted
before its tombstone write, so a wedged write reached a re-entrant onFailed()
that returned early on the phase guard and never reached the logging handler.
Use the two-argument then form so task rejection and lifecycle settlement
failure stay on separate paths.
* fix(channels): satisfy ingress CI guards
* feat(gateway): share the canonical browser-origin policy with plugins
Export resolveAcceptedBrowserOrigin through openclaw/plugin-sdk/webhook-request-guards
so browser-facing plugin routes reuse the Gateway's real origin contract instead of a
narrow allowedOrigins array check. Private LAN/Tailnet Control UI loads and the
Host-header fallback were previously rejected with 403 by plugin offer routes while the
Control UI itself worked.
Moves the loopback/forwarded-header helpers to net.ts (re-exported from auth.ts) so the
guard can delegate without importing gateway auth, and migrates the Codex realtime
broker onto the shared seam.
* feat(talk): let providers own agent delegation for realtime voice
Adds an optional runAgentConsult callback to the browser-session create request and
injects the existing embedded consult runtime from talk-client, bound to the same agent
and session key the GA tool path uses. Providers whose realtime protocol delegates work
through their own control channel (rather than GA function calls) can now reach the
OpenClaw agent without a client round-trip.
Threads the effective per-session model into browser-session capability resolution so a
request-level model override selects the right capability set, and propagates a caller
abort signal into consultRealtimeVoiceAgent so a superseded delegation stops its run.
* feat(openai): support GPT-Live realtime voice over ChatGPT OAuth
Implements OpenAI's quicksilver/frameless session natively for Talk browser sessions.
The Gateway creates the WebRTC call (multipart sdp+session to https://api.openai.com/v1/live)
and owns the sideband control socket, so the browser never holds upstream credentials;
delegation.created events run through the OpenClaw agent and stream back as speakable
context appends.
Verified end-to-end on 2026-07-28 against a ChatGPT Pro OAuth profile: call create 201
with an rtc_* id and answer SDP, sideband session.started, session.close teardown.
ChatGPT OAuth is preferred over a Platform API key because /v1/live access for platform
keys is waitlist-gated; the legacy chatgpt.com backend route returns 403 for every model
and protocol version and is not used.
Accepted models are gpt-live-1-codex and gpt-live-1-boulder-alpha; the voice allowlist is
the ten values the route actually accepts, since an invalid voice is rejected at call
creation and cannot be repaired afterwards (session.update reports immutable_field_update).
* docs: document GPT-Live Talk support and its route gotchas
Records the working route and auth, the accepted models and voices, the browser-only
scope, and the two traps that cost the most time: the chatgpt.com backend route returns
403 Voice session access denied for every model, and that same 403 is also what an
invalid voice returns, so it must not be read as an account entitlement block.
* fix(openai): resolve GPT-Live CI failures
* refactor(openai): own zod runtime dependency
* fix(openai): satisfy lint and live-shard gates for GPT-Live
Types the retry-delay finish callback as Error so the rejection reason is provably an
Error at the call site; the abort path already normalized a non-Error AbortSignal reason,
but the unknown parameter type hid that from static analysis.
Registers the new GPT-Live live test in the native-live-extensions-openai shard
expectation. The shard selector already picked the file up from the real tree; only the
hardcoded list in the tooling test lagged.
* fix(openai): clean up post-rebase capability resolver
* fix(openai): preserve GPT-Live delegation fragments
* fix(openai): close GPT-Live sideband handoff race
* fix(openai): accept UUID GPT-Live call ids
* style: apply oxfmt to GPT-Live sources and Talk docs
* style: format Talk docs after rebase
* fix(openai): keep GPT-Live transcript context across ignored delegations
* feat(memory): add provenance and recall metadata to the memory index
* feat(memory): provenance-gated promotion and capture hygiene
* feat(dreaming): LLM consolidation with deterministic gates, on by default
* feat(active-memory): deterministic recall lane with escalation default
* feat(memory): user model file and standing intents
* docs(memory): document the memory architecture
* fix(memory): live-QA fixes — metadata writers, provenance classes, intent scope, claim accumulation