Commit Graph

14284 Commits

Author SHA1 Message Date
Vincent Koc
d1b268f7f7 fix(qa): normalize completed wait envelopes 2026-06-23 05:13:35 +02:00
Vincent Koc
19627c7dd9 fix(memory): improve node:sqlite unavailable guidance (#95916)
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Song Luo <133665654+rrrrrredy@users.noreply.github.com>
2026-06-23 02:12:47 +00:00
Vincent Koc
abd8a46b0a improve: reduce hot-path linear scans and redundant I/O (#95697)
Merged via squash.

Prepared head SHA: 67f2678a34
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-23 10:11:18 +08:00
Marcus Castro
ce391dc382 fix(whatsapp): preserve durable reply target (#95914) 2026-06-22 23:05:35 -03:00
Vincent Koc
2205f50016 test(qa): satisfy history reply lint 2026-06-23 04:01:11 +02:00
Vincent Koc
d716dfd532 test(qa): wait for live history replies in flow scenarios 2026-06-23 04:01:11 +02:00
Vincent Koc
5822e8074d test(qa): accept completed agent wait status 2026-06-23 04:01:11 +02:00
Dallin Romney
27711b500c ci: add maturity scorecard renderer (#94272) (#95901)
* ci: add maturity scorecard renderer

* ci: render qa scorecard evidence

* ci: type maturity docs renderer

* ci: tighten maturity artifact inputs

* ci: move maturity renderer under qa scripts

* ci: share maturity score schema

* ci: centralize maturity taxonomy validation

* ci: move maturity scores under qa

* ci: remove docs maturity score source

* docs: simplify maturity scorecard output

* docs: commit generated maturity scorecard

* docs: group maturity pages

* docs: simplify maturity scorecard dates

* docs: promote maturity nav tab

* docs: clean up maturity pages

* docs: remove maturity outline page

* docs: filter maturity taxonomy doc links

* docs: simplify maturity taxonomy tables

* docs: keep artifact taxonomy links

* docs: simplify lts scorecard display

* docs: clarify maturity score definitions

* docs: derive maturity coverage from evidence

* docs: hide maturity scorecard until evidence

* docs: remove placeholder maturity pages

* docs: keep maturity scores out of pr

* ci: open maturity scorecard docs pr
2026-06-22 18:55:06 -07:00
Vincent Koc
def4b51485 fix(qa): gate smoke profile scenarios by channel driver 2026-06-23 09:34:52 +08:00
ly-wang19
d84a8b1506 fix(discord): reserve closing-fence space on fence-closing lines (#95661)
`chunkDiscordText` reserved closing-fence space from the post-line fence state
(`nextOpenFence`), but a flush during a line's segment loop appends the closing
fence based on the still-open `openFence`, which is only advanced after the
line. On a line that closes a fence yet carries trailing text, `reserveChars`
was 0 while `flush()` still appended a `` ``` ``, producing a chunk of
`maxChars + 4` (e.g. 2004 > 2000) that Discord rejects with HTTP 400.

Reserve against `nextOpenFence ?? openFence` so whichever fence a flush can
close is accounted for, keeping a fence-closing line's chunk within `maxChars`.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 01:28:14 +00:00
Vincent Koc
43f2b61f3b test(qa): keep image generation fixture on mock lane 2026-06-23 02:35:02 +02:00
Yuval Dinodia
0ec12df245 fix(memory-wiki): preserve human notes block on source re-ingest (#95614)
* fix(memory-wiki): preserve human notes block on source re-ingest

Re-ingesting an existing source regenerated the page with an empty
wrote inside the human-managed markers. This broke the documented
contract that human note blocks are preserved, and diverged from the
synthesis and chatgpt-import writers that already preserve the block.

When a source page already exists, read it and re-inject its human Notes
block before writing. The block is located by scanning past the fenced
the content, then taking the first human start marker and the last end
marker, so the whole Notes block is preserved verbatim even when the
source content or the note text contains the markers or Markdown
headings. The same preservation is applied to writeImportedSourcePage so
the bridge and unsafe-local source-update writers keep notes too. New
page creation is unchanged.

Adds regressions for plain re-ingest, marker text in source content,
marker text inside the note, a heading inside the note, and an imported
source page update.

* fix(memory-wiki): preserve notes on CRLF source pages
2026-06-23 00:33:45 +00:00
Vincent Koc
086c629556 test(qa): scope provider-sensitive flow fixtures 2026-06-23 02:17:20 +02:00
Vincent Koc
befe04f465 test(qa): accept Sonnet max thinking support 2026-06-23 01:57:43 +02:00
ANIRUDDHA ADAK
82316c2f45 test: make qqbot symlinked media helper test robust on Windows
Gate the QQ Bot symlink-media helper regression test on actual file-symlink capability, so environments that cannot create file symlinks skip that specific test while capable hosts still run it.

Validation:
- Windows Vitest proof in the PR body: `extensions/qqbot/src/engine/utils/file-utils.test.ts` passed with 4 tests passed and 1 symlink test skipped when file symlinks were unavailable.
- Current CI is clean at `cb7d5a162e24f7ec5be6985e97b2b74ae45b20f9`, including the refreshed Real behavior proof run `27992101343`.

Co-authored-by: Aniruddha Adak <aniruddhaadak80@users.noreply.github.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-23 07:54:53 +08:00
Vincent Koc
264b37e9d2 test(qa): avoid redacted config cleanup patch 2026-06-23 01:39:39 +02:00
xiayu
fc15c58715 fix(memory-core): report active dreaming phases in status (#93113)
* fix(memory-core): report active dreaming phases in status

* fix(memory-core): repair active dreaming status phases

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-23 07:16:14 +08:00
Dallin Romney
de9c94cbbb feat(qa): forward shared suite flags to multipass runner (#91506) 2026-06-22 15:48:05 -07:00
Dallin Romney
63b13ea837 feat(qa): crabline channel driver (#91502)
* feat(qa): add crabline channel driver seam

* feat: run crabline channel driver smoke

* chore: keep crabline qa dependency dev-only

* refactor(qa): keep crabline driver details opaque

* chore(qa): pin crabline to merged driver API

* feat(qa): drive channel driver from profiles

* fix(qa): declare crabline runtime peer

* feat(qa): resolve crabline channel from scenarios

* feat(qa): treat unsupported profile channels as coverage gaps

* Revert "feat(qa): treat unsupported profile channels as coverage gaps"

This reverts commit 65a9701655.

* fix(qa): adapt crabline driver to chat sdk cli

* refactor(qa): pass channel driver metadata directly

* chore(qa): update crabline provider pin

* chore(qa): default channel scenarios to driver

* chore: repair qa dependency lockfile

* chore: allow native qa dependency builds

* fix(qa): satisfy crabline driver lint

* fix(qa): satisfy crabline ci gates

* Use crabline transport for smoke QA profile

* fix(qa): keep crabline driver opt-in

* fix(qa): reuse crabline telegram driver token

* fix(qa): route smoke profile through crabline

* fix(qa): run full smoke profile lane

* fix(qa): remove smoke scenario workflow filter

* fix: stabilize crabline smoke qa profile

* fix: pin crabline qa dependency

* test: keep crabline smoke credential-free

* fix: skip visible reasoning lane for crabline smoke

* fix: unblock crabline qa ci

* Update crabline dependency

* Pin crabline to merged main

* Use Crabline fake provider servers
2026-06-22 15:24:59 -07:00
Efe Büken
739e6cbbf8 fix(minimax): request hex TTS output explicitly
* fix(minimax): request hex TTS output explicitly

* fix(minimax): request hex TTS output explicitly

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-23 06:03:55 +08:00
Dallin Romney
ed2dfee7d7 feat(qa): expose active memory toggles to scenarios (#95858) 2026-06-22 14:26:37 -07:00
zhang-guiping
769579bcf0 fix(opencode-go): streaming completes when provider ends responses (#93965)
* fix(opencode-go): abort stalled SSE streams at provider-owned raw boundary

opencode-go routes through the shared OpenAI-compatible completions provider,
where a stalled SSE socket (provider emits tokens then never closes the stream)
hangs the gateway until stuckSessionAbortMs (~622s) and surfaces as
'LLM request failed' / 'Request was aborted'. Issue #93610 reports ~90% of
opencode-go cron jobs failing intermittently this way.

Add a provider-owned stream wrapper at the opencode-go raw SSE boundary that
injects an AbortController into the underlying OpenAI SDK request and aborts
it after a configurable idle window (default 30s, far below 622s) elapses
without any forward-progress event. The wrapper is:

- Provider-scoped: only applies when model.provider === 'opencode-go'; the
  shared openai-completions.ts path is untouched.
- Abortable: calls controller.abort() on the injected AbortSignal, which
  propagates through OpenAI SDK requestOptions.signal and genuinely
  interrupts the underlying fetch/stream (not just iterator return()).
- Idle-based: every event (text/tool/thinking delta, including delayed
  usage-only chunks) refreshes the timer; natural completion (done/error)
  cancels it. Normal delayed usage-only completion is preserved.
- Boundary-terminal: pushes a terminal { type: 'error', reason: 'aborted' }
  event downstream so consumers do not hang.

TDD: stream-termination.test.ts covers (a) stalled stream after first
progress is aborted within the idle window with a downstream 'aborted'
terminal event, and (b) normal delayed completion within the idle window
is not aborted and the done event is forwarded unchanged.

* fix(opencode-go): align stalled-stream idle default with runtime (120s)

Match the runtime's shared `DEFAULT_LLM_IDLE_TIMEOUT_MS` (120s) so
non-cron interactive opencode-go runs see no behavior change versus the
existing watchdog. Cron runs — for which the runtime disables its idle
watchdog entirely (`resolveLlmIdleTimeoutMs` returns 0 when trigger is
cron and no explicit timeout is set) — still get provider-owned
termination well before the ~622s stuck-session recovery.

Refs #93610

* fix(opencode-go): satisfy CI lint and test type checks

- Remove unnecessary `?? {}` fallback in spread (oxlint
  no-useless-fallback-in-spread).
- Drop non-narrowing `!` on the wrapper return type; use
  `await Promise.resolve(...)` to collapse the
  `StreamLike | Promise<StreamLike>` union before `for await`.

Refs #93610

* fix(opencode-go): arm stalled-stream idle timer only after first event

The wrapper armed the idle timer before the first upstream event, which
would mis-abort slow time-to-first-byte requests — including the
opencode-go cron runs that the runtime deliberately leaves uncapped via
resolveLlmIdleTimeoutMs. Arm only after the first forwarded event, and
add regression coverage for the slow-first-event path.

* fix(opencode-go): cover stalled stream first event

* fix(opencode-go): respect explicit stream timeout

* fix(opencode-go): preserve first-event timer after synthetic start

* fix(opencode-go): satisfy stream termination test lint

* fix(opencode-go): distinguish synthetic stream preambles

* fix(opencode-go): route stalled streams through failover
2026-06-22 19:57:21 +00:00
Vincent Koc
013e33c6d3 fix(telegram): avoid duplicate progress headings 2026-06-22 21:43:47 +02:00
Moeed Ahmed
5cafe4b0cf fix(telegram): keep bot reply answers anchored to current message (#90475)
Co-authored-by: Moeed Ahmed <moeedahmed@Moeed-Mac-mini.local>
2026-06-22 19:17:07 +00:00
Darren2030
c4cac33af6 fix(openrouter): expand short canonical model IDs to upstream API slugs (fixes #95198) (#95268)
- Add OPENROUTER_SHORT_TO_API_MODEL_ID map for short model refs like
  openrouter/deepseek-v4-flash that OpenClaw surfaces but OpenRouter API
  expects as deepseek/deepseek-v4-flash.
- In normalizeOpenRouterApiModelId, expand short refs before falling back
  to the existing namespaced strip logic.
- Add unit tests covering short refs, long refs, native routes, and
  pass-through cases.
- Add standalone reproduction script that verifies all normalization cases.
2026-06-22 19:15:25 +00:00
areslp
bfbf25e234 fix(feishu): show voice message duration via upload duration (#89172)
Voice/audio messages sent to Feishu (opus) play fine but show no duration
on the bubble. Feishu derives the voice-bubble duration from the `duration`
parameter of the file upload API (`im/v1/files`); the audio message content
only carries `{file_key}` and has no duration field, so the duration was
never set.

`sendMediaFeishu` now probes the outgoing audio with `ffprobe` and passes the
result as the upload `duration` (ms). It probes the buffer that is actually
sent (after the existing voice transcode, which caps length via
`MEDIA_FFMPEG_MAX_AUDIO_DURATION_SECS`), so the reported length matches what
is played. Probing is best-effort: on failure it logs and omits the duration,
and the message still sends. The audio message content is unchanged.

Fixes #53798

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 19:13:14 +00:00
ly-wang19
81e1ec467c fix(imessage): strip leading echo corruption markers in the persisted echo cache (#94442)
The persisted iMessage echo-dedupe cache normalized text with CRLF->LF + trim only, not the leading attributedBody corruption-marker stripping the in-memory echo cache applies (#93511). The persisted 12h cache is the only matcher once the 4s in-memory text TTL expires, so a delayed reflected own-message echo whose text decoded with a leading NUL/replacement/BOM marker did not match the clean stored send -- the agent's own message was re-ingested as fresh inbound, causing a self-reply loop.

Extract the marker-stripping into a leaf module shared by both echo caches (the in-memory cache already imports the persisted one, so importing back would be a cycle) and apply it in the persisted normalizeText, so both caches strip identically.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 19:07:45 +00:00
Zechen Wang
4d636335db fix(google): add gemini-3.5-flash model catalog entry (#94726)
* fix(google): add gemini-3.5-flash model catalog entry

gemini-3.5-flash was missing from the bundled Google model catalog,
causing it to silently fall back to DEFAULT_CONTEXT_TOKENS (200k)
instead of its documented 1,048,576-token input window.

Add the catalog entry and forward-compat routing so the model
resolves with the correct context window.

Closes: openclaw/openclaw#94723
Co-Authored-By: Claude <noreply@anthropic.com>

* chore: retry CI (flaky test)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-22 18:28:01 +00:00
ly-wang19
d63389ccf6 fix(qqbot): recognize GFM table separators with one or two dashes (#95637)
`isTableSeparatorLine` required 3+ dashes per cell (`/^:?-{3,}:?$/`), but a
GFM delimiter cell needs only one or more dashes. So a valid table whose
separator used 1 or 2 dashes (e.g. `|--|--|`) was not recognized: the header
stayed pending and was silently overwritten by each following row, so the
table's header, separator, and every row but the last vanished from the sent
message.

Accept `-+` so valid GFM separators are recognized, matching the spec and the
sibling LINE channel. Every existing test separator already uses 3+ dashes, so
they are byte-identical.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:27:01 +00:00
Vincent Koc
96c6f8022c fix(auto-reply): suppress quoted silent replies 2026-06-23 02:24:29 +08:00
Jason O'Neal
92264fbb8f fix(ollama): skip auto-discovery for remote/cloud base URLs (#93956)
* fix(ollama): skip auto-discovery for remote/cloud base URLs

When the Ollama provider base URL points to a remote/cloud instance
(e.g. ollama.com), the plugin should not auto-discover all available
models via /api/tags. Cloud instances are shared tenants where the
provider manages the model catalog; users should only get models they
explicitly configure.

- Add remote-baseUrl guard in resolveOllamaDiscoveryResult
- Local/loopback URLs still auto-discover as before
- Remote URLs with explicit models return only those models
- Remote URLs without explicit models return null (skip discovery)
- Add tests covering remote guard, explicit models, and local fallback

* fix ollama cloud discovery ci

* fix(ollama): narrow discovery guard to hosted Ollama Cloud only

The previous guard blocked auto-discovery for ALL remote base URLs
without explicit models. This was too broad — it also blocked
self-hosted Ollama instances at custom domains (e.g.,
https://ollama.mycompany.com).

Replace the !isLocalOllamaBaseUrl() check with a targeted
isHostedOllamaCloud() check that only matches *.ollama.com
hostnames. Remote self-hosted Ollama endpoints now correctly
auto-discover as before.

Add isHostedOllamaCloud() helper with unit tests and a
regression test confirming remote self-hosted URLs still
auto-discover.

* fix(ollama): ensure models array in explicit-models return path

* fix(ollama): replace deprecated config-types import with local type

The openclaw/plugin-sdk/config-types subpath is deprecated and flagged
by the CI architecture check. Replace it with a local OllamaProviderConfigInput
type alias defined from non-deprecated provider-model-shared exports.

- discovery-shared.ts: define OllamaProviderConfigInput locally
- provider-base-url.ts: define OllamaProviderConfigInput locally
- Both files: remove import from openclaw/plugin-sdk/config-types

* chore(ollama): drop unrelated formatting churn
2026-06-22 18:08:05 +00:00
Dirk
96e49705a6 fix(matrix): prune finished fake-indexeddb transactions to prevent OOM (#94942)
fake-indexeddb@6.2.5 retains finished transactions in raw.transactions
array indefinitely. For Matrix E2EE crypto stores, this causes unbounded
heap growth and eventual OOM crashes.

Add a transaction pruner that patches IDBDatabase.prototype.transaction
to automatically remove finished transactions for Matrix crypto databases
(::matrix-sdk-crypto and ::matrix-sdk-crypto-meta suffixes).

Fixes #90455
2026-06-22 18:06:55 +00:00
YEEE
e3a496a29a [agent] fix: repair telegram cache message types (#82909) 2026-06-22 18:04:28 +00:00
Mark
e8a31ddbce fix(xai): request encrypted reasoning include for all reasoning models (#95686)
Merged via squash.

Prepared head SHA: 8b3be0aaab
Co-authored-by: geraint0923 <923382+geraint0923@users.noreply.github.com>
Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
Reviewed-by: @fuller-stack-dev
2026-06-22 11:50:50 -06:00
wood fish
1fc4342a02 fix(ollama): honor memory embedding output dimensionality (#94811) 2026-06-22 17:49:43 +00:00
Vincent Koc
0276cbbce2 test(active-memory): isolate empty recall mock 2026-06-22 19:33:21 +02:00
Wynne668
f3d92936b5 fix(memory-wiki): retry transient source-page rewrite race (#94443)
A concurrent atomic rewrite (write-temp + rename) of a memory-wiki source
page by the bridge re-export made fs-safe's opened-fd identity check fail
with `path-mismatch`, which the page write rethrew as a fatal "Refusing to
write" error and aborted the whole wiki_status / source-sync call. The race
is transient and benign: the file is replaced under the open handle and the
concurrent writer lands equivalent content.

Retry briefly on `path-mismatch` (the rename window closes sub-ms) and
rethrow unchanged on exhaustion, so persistent failures (directory
collision, not-file) and symlink/path-alias swaps still hard-fail exactly
as before. The identity guard is untouched; only the benign rename race is
retried, matching the sibling read path that already treats path-mismatch
as transient.

Extracts the guarded-write logic duplicated by source-page-shared.ts and
okf.ts into one writeGuardedVaultPage helper so both write paths get the
fix and the copy is removed.

Closes #92134

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 17:22:15 +00:00
Ted Li
405896a4a3 fix(lmstudio): canonicalize variant model keys (#95401)
* fix(lmstudio): canonicalize variant model keys

* fix(lmstudio): retain canonical key after preload failures

* fix(lmstudio): keep canonical key during preload cooldown
2026-06-22 17:20:54 +00:00
Vincent Koc
86ea382121 fix(discord): preserve progress preview final edits 2026-06-22 18:35:14 +02:00
Mike Harrison
e1ecfa5200 fix(diagnostics-otel): keep full model id on spans instead of collapsing to "unknown" (#89981)
* fix(diagnostics-otel): keep full model id on spans (was collapsing to "unknown")

* test(diagnostics-otel): cover slash model span attribution

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-22 16:32:50 +00:00
Hannes Rudolph
69c4d1aa85 Revert "feat(discord): add server management helper actions"
This reverts commit ae22f485ec.
2026-06-22 10:20:19 -06:00
Hannes Rudolph
ae22f485ec feat(discord): add server management helper actions 2026-06-22 10:18:28 -06:00
Vincent Koc
905c9759a7 refactor(voice-call): share path normalization 2026-06-22 22:18:49 +08:00
Vincent Koc
9c85b812fe chore(tlon): remove inert SSRF policy helper 2026-06-22 22:12:48 +08:00
Josh Lehman
d3781cc4b8 refactor: add memory and QMD session identity mapping (#95087) 2026-06-22 06:28:54 -07:00
Vincent Koc
7626ca38b3 chore(release): refresh generated metadata 2026-06-22 21:25:38 +08:00
Vincent Koc
a4eb49a176 refactor(qa): share gateway message text extraction 2026-06-22 20:25:26 +08:00
Vincent Koc
db21588636 refactor(qa): share suite summary file loading 2026-06-22 20:24:20 +08:00
Vincent Koc
88b64e4b86 fix(discord): drain queued voice replies after stream close 2026-06-22 20:20:56 +08:00
Vincent Koc
927d0aefeb refactor(elevenlabs): share TTS request assembly 2026-06-22 19:52:02 +08:00