Commit Graph

19174 Commits

Author SHA1 Message Date
Vincent Koc 78fd4f99fe test(voice-call): keep timer fixture runtime-neutral 2026-07-31 04:02:58 +08:00
Vincent Koc 04afcf51c3 fix(voice-call): hold idle media shutdown barrier 2026-07-31 04:02:58 +08:00
Vincent Koc 695d18458f fix(voice-call): hold shutdown barriers through drain 2026-07-31 04:02:58 +08:00
Vincent Koc 4beffe5c72 test(voice-call): model realtime handler shutdown 2026-07-31 04:02:58 +08:00
Vincent Koc e29f3a2e62 fix(voice-call): share runtime stop completion 2026-07-31 04:02:58 +08:00
Vincent Koc 6758c61135 fix(voice-call): await owned sockets during server stop 2026-07-31 04:02:58 +08:00
Vincent Koc e4f7c83526 fix(voice-call): close realtime sockets on shutdown 2026-07-31 04:02:58 +08:00
Vincent Koc 1a35ed0008 fix(voice-call): close classic media sockets on shutdown 2026-07-31 04:02:58 +08:00
joshavant dd4728305f test(qa-lab): use upload-safe Tuwunel fixture 2026-07-30 14:57:44 -05:00
joshavant fe654eaacd test(qa-lab): refresh Matrix Tuwunel fixture 2026-07-30 14:57:44 -05:00
joshavant 12b9e7c683 test(msteams): satisfy async lint 2026-07-30 14:20:11 -05:00
joshavant 834559d043 fix(msteams): settle stopped stream replacements 2026-07-30 14:20:11 -05:00
joshavant c659c21672 fix(msteams): preserve acknowledged stream settlement 2026-07-30 14:20:11 -05:00
Vincent Koc 544b9d5e9f test(voice-call): avoid unbound session mock 2026-07-31 02:35:51 +08:00
Vincent Koc 5d51b93a77 test(voice-call): isolate media lifecycle coverage 2026-07-31 02:35:51 +08:00
Vincent Koc 30abc2d653 test(voice-call): await duplicate start cleanup 2026-07-31 02:35:51 +08:00
Vincent Koc c047d57fba test(voice-call): cover duplicate media starts 2026-07-31 02:35:51 +08:00
Vincent Koc c3f1efa10a fix(voice-call): reject duplicate media starts 2026-07-31 02:35:51 +08:00
Josh Avant ce67ffb70e feat(agents): add tool-free isolated completion (#114343)
* feat: add isolated pure-inference completion

* fix(google): block ambient system prompt writes

* docs: refresh generated map
2026-07-30 13:24:45 -05:00
Vincent Koc 7b581eccc1 test(openai): cover GPT-Live delegation output bounds 2026-07-31 01:30:23 +08:00
Vincent Koc ef4cebb263 fix(openai): bound GPT-Live delegation output 2026-07-31 01:30:23 +08:00
Vincent Koc 0822e8d39e fix(qa): preserve missing Ollama cache telemetry (#116424) 2026-07-30 16:37:54 +00:00
Omar Shahine 9bebf7ac43 fix(imessage): bold approval prompt labels in poll mode (#116221)
* 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>
2026-07-30 09:23:47 -07:00
Vincent Koc e96b9d2cd0 improve(ui): verify llama.cpp model setup 2026-07-30 23:41:58 +08:00
Vincent Koc 90a22b4f50 chore(test): run browser copilot E2E in CI (#116407)
* test(browser): run copilot E2E in CI

* test(browser): stabilize copilot E2E synchronization

* test(browser): wake extension workers deterministically

* test(ci): route browser copilot command changes
2026-07-30 23:20:34 +08:00
Vincent Koc ca1328dddb Merge pull request #116285 from openclaw/fix/control-ui-session-dedupe
* origin/fix/control-ui-session-dedupe:
  chore: leave release notes to release flow
  fix(ui): deduplicate gateway-native session hosts
2026-07-30 22:53:53 +08:00
Shakker ea82059e02 fix: satisfy ClickClack lint checks (#115484) 2026-07-30 15:42:18 +01:00
Shakker 7f35fa8ab7 fix: publish top-level ClickClack mention config (#115484) 2026-07-30 15:42:18 +01:00
Shakker e95fe13eb2 perf: use normalized ClickClack group lookups 2026-07-30 15:42:18 +01:00
Shakker f44fdec2b9 fix: preserve inherited ClickClack group policy 2026-07-30 15:42:18 +01:00
Shakker c0f8288daa fix: route ClickClack discussion mentions correctly 2026-07-30 15:42:18 +01:00
Shakker 154e67b1e2 fix: recognize ClickClack handle mentions 2026-07-30 15:42:17 +01:00
Jacqueline Henriksen ba9e9fec13 fix: gate ClickClack group replies on mentions 2026-07-30 15:42:17 +01:00
Vincent Koc c7d1205d51 fix(google): guide broken CLI profiles to supported auth 2026-07-30 22:40:20 +08:00
Vincent Koc 5504f1e9a1 test(reef): remove false-green live guard smoke (#116393) 2026-07-30 20:16:28 +08:00
Vincent Koc 3e7ecb3aea test(comfy): evaluate live guards after setup (#116388) 2026-07-30 19:58:35 +08:00
Vincent Koc f6d5066bb3 test(discord): align progress timing expectations (#116377) 2026-07-30 19:11:01 +08:00
Dallin Romney 424c36a2d5 fix(qa): prevent Slack cleanup from stalling profile runs (#116361)
* fix(qa): release Slack leases after gateway stop

* fix(qa): preserve async Slack cleanup contract

* fix(qa): expose post-gateway adapter cleanup
2026-07-30 19:05:49 +08:00
Ayaan Zaidi c4b82609b7 fix(agents): compare shell tool names case-insensitively and stop re-parsing tool labels
Progress-draft lines recovered their detail by string-slicing the label formatToolAggregate had just rendered, and three sites decided "is this a shell tool?" against lowercase spellings only. The Claude CLI sends "Bash", so those checks missed, the slice returned nothing, and every CLI tool call rendered a line with no detail: Telegram printed the icon twice and the tool-summary payload could no longer merge, leaving a second id-less line per call.

formatToolAggregateParts now returns the label with the detail it composed, so a line cannot disagree with its own text, and one predicate owns the shell question across all four sites. Proven live on the Claude CLI backend: two lines with a doubled icon became one.
2026-07-30 19:52:08 +09:00
Jesse Merhi f1ee2a3098 fix(diagnostics-otel): agent turns split into one-span traces instead of a trace tree (#116246)
* fix(diagnostics-otel): keep parent span links across long turns

Retained trusted span contexts translate a completed lifecycle span's
diagnostic span id to the real OTel span context. That table was evicted
5s after run.completed, so children of a longer turn missed their parent
and OTel minted a fresh trace id for each one, silently splitting a turn
into single-span traces.

Retention is now identity-based and lives for the service lifetime,
bounded by MAX_RETAINED_TRUSTED_SPAN_CONTEXTS, which removes the timing
race and the drain/timeout cleanup subsystem.

Also nests openclaw.exec under its run: the exec event now carries a
trusted trace context and the recorder resolves the ambient run scope.

* fix(diagnostics-otel): key retained span contexts by diagnostic trace id

Retained lifecycle span contexts were stored under the span's OTel trace id
but looked up with the event's diagnostic trace id. Those are different id
spaces, so every post-completion parent lookup missed and each straggler
span started a brand-new trace.

The mocked suite could not catch this: its tracer reports the same trace id
the test feeds in, collapsing both id spaces into one value. Adds a boundary
test that runs the real OTel SDK and OTLP/protobuf exporter against a local
receiver and asserts on exported span bytes.

* fix(diagnostics-otel): harden span-linking contract after review

Review findings on the parent-span linking fix:

- completeTrackedLifecycleSpan now takes the DiagnosticTraceContext instead of a
  bare trace id beside a span id. Two adjacent hex strings let a transposition
  compile clean and silently reinstate split traces; DiagnosticTraceContext is
  the only shape an OTel SpanContext cannot satisfy (traceFlags string vs number).
- internalOrTrustedTraceContext composes normalizedTrustedTraceContext rather
  than spelling the trust predicate a third time.
- Corrected comments that claimed OTel ids never equal diagnostic ids. Spans
  parented from an upstream traceparent do adopt the diagnostic trace id; the
  removed guard only ever misfired on root lifecycle spans.
- Exec comment now states the real parent: the openclaw harness opens no run
  scope, so exec nests under openclaw.harness.run.

Test gaps closed:

- The core emitter switch was untested; reverting it kept every test green.
  The pty-fallback test now asserts the emitted metadata.
- The boundary test covered only run.completed of three lifecycle owners; it now
  covers harness.run.completed and message.processed too, each with a straggler.
- Dropped the service-context cast for the typed helper, which caught a bogus
  context.assembled field, and moved teardown into afterEach so a failed
  assertion cannot leak the real NodeSDK across files.
- Scoped the one-trace assertion to this turn's spans; faked Date so a lazy
  Date.now expiry cannot pass.

Docs: exec and tool spans now listed as staying on an upstream request trace.

* fix(diagnostics-otel): keep late children on the trace on every terminator

Native review found three correctness gaps in the previous commit:

- Exec spans could be exported naming a parent span id nothing ever emits. The
  ambient lookup fell through to a remote-parent fallback built from diagnostic
  ids, which is a regression from the previous clean-root behavior and breaks
  waterfalls and parent-id-keyed backends. Exec now resolves only spans this
  process exported and stays a root on a miss; message spans keep the remote
  fallback because their context can come from an inbound traceparent.
- harness.run.error never retained its span context, so an aborted turn still
  split. For the openclaw harness that span is the only ancestor a late child
  has, and aborted turns emit no run.completed.
- completeTrackedLifecycleSpan no longer takes a redundant spanId.

The boundary test now runs through the OPENCLAW_OTEL_PRELOADED seam with an
in-memory exporter and releases the global tracer provider in teardown. A
NodeSDK cannot be unregistered, so the old version would have made any later
real-SDK test silently export nothing. That also deletes the hand-rolled OTLP
protobuf decoder. Added guards for the aborted-turn path and for exec staying
parentless; both are mutation-verified.

* fix(diagnostics-otel): age retained parent contexts out after 10 minutes

Retention had no time bound at all, so a command backgrounded by a turn could
finish hours later and still attach to a parent that ended long before. Backends
derive trace latency from the span envelope, so a 30s turn rendered as hours with
a child extending past its parent.

The horizon is checked lazily on lookup rather than on a timer: a timer firing
mid-turn is exactly what silently split traces before. Past the horizon a
straggler starts its own trace, which only loses causality for a span that would
have skewed its parent's duration anyway.

The two bounds now pin each other - shrinking the horizon to the old 5s window
fails the original regression tests, and removing it fails the new horizon test.

* fix(diagnostics-otel): retain parent contexts until capacity
2026-07-30 20:41:41 +10:00
Vincent Koc 8a3f5c862b fix(plugin-sdk): ship documented public typings (#116345)
* fix(plugin-sdk): ship documented public typings

* fix(plugin-sdk): refresh public contract artifacts
2026-07-30 18:20:07 +08:00
pash-openai e52354ea13 fix(build): pin typebox to a published release (#116333) 2026-07-30 09:58:51 +00:00
WhatsSkiLL e5cee36b46 fix(memory): retry failed queued session targets (#115923)
* fix(memory): retain failed queued sync targets

* fix(memory): drain retained targets on idle sync

* test(memory): prove idle queued sync recovery

* fix(memory): preserve queued sync ownership

* fix(memory): avoid queued sync self-deadlock

* fix(memory): stop queued recovery during close

* fix(memory): clear retained sync state on close

* test(memory): prove live queued rejection transition

* fix(memory): enforce sync repro invariants

* test(memory): bound archive recovery proof

* test(memory): seed archive proof transcript

* test(memory): exercise archived transcript recovery

* chore(knip): register memory sync repro

* fix(memory): reject blank queries before settings

* style(memory): satisfy queue recovery lint

* test(memory): align doctor migration expectations

* test(memory): insert explicit provenance fixture

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-30 02:47:59 -07:00
Dallin Romney 714a46d7f2 fix(qa): align live scenario selection (#115767) 2026-07-30 16:59:01 +08:00
Ayaan Zaidi 21d3533460 fix(channels): ack mentions in groups that do not require them
The group-mentions ack gate returned false whenever a group did not require mentions, conflating group policy with whether this message mentioned the agent. Under the default scope, mentioning the agent in a group configured to answer everything produced no ack at all, so the user had no signal the turn was picked up until the reply arrived.

Behavior change on a default path: those groups now show the 👀 ack (and the lifecycle status reactions when messages.statusReactions.enabled is true) on mentions. Mention-required groups, group-all, unmentioned messages, and off/none are unchanged. The gate no longer reads requireMention, so the parameter is gone from the shared type and all channel call sites.

Proven live on Telegram across three configurations, including a no-mention control confirming group-mentions did not become group-all.
2026-07-30 17:58:46 +09:00
Dallin Romney b765ada174 fix: stop WhatsApp restart loop after remote logout (#114445) 2026-07-30 16:48:32 +08:00
Dallin Romney 184069f3df fix(qa): make Slack observer lazy and abortable (#116312) 2026-07-30 16:46:49 +08:00
Vincent Koc 6e4f67f084 Merge remote-tracking branch 'origin/main' into fix/control-ui-session-dedupe
* origin/main: (25 commits)
  fix(qqbot): use Gateway timezone for reminders (#116294)
  test(openai): cover out-of-order named mark acks
  docs(openai): clarify cumulative playback marks
  test(openai): cover sustained unnamed mark acknowledgements
  fix(openai): preserve playback acknowledgement order
  test(openai): verify bounded playback acknowledgements
  fix(openai): bound realtime playback marks
  test(agents): mock incremental registry persistence (#116307)
  fix(memory-core): MEMORY.md compaction deletes user notes written under a promotion-style heading (#116180)
  feat(reply): annotate recent history images (#100866)
  chore(ios): refresh native i18n inventory
  fix(ios): isolate capability router handlers
  docs(ios): cut 2026.7.22 release notes
  docs(hooks): document validation responses
  test(qa): assert hook account rejection reasons
  fix(gateway): validate hook delivery accounts
  perf(gateway): bound prepared runtime startup work (#116261)
  fix(agents): prevent registry stalls during large fan-outs (#116286)
  fix(sqlite): preserve replaced snapshot targets on Windows (#116284)
  fix(ci): load frozen shard runner without repository fetch (#116273)
  ...
2026-07-30 16:37:47 +08:00
Vincent Koc c568f93b03 fix(google): retire Gemini CLI OAuth setup 2026-07-30 16:33:33 +08:00
Vincent Koc 91dca69dae fix(qqbot): use Gateway timezone for reminders (#116294) 2026-07-30 16:32:18 +08:00