Commit Graph

66940 Commits

Author SHA1 Message Date
Alix-007
dd6143f60c fix(signal): bound container REST response reads
Bounds Signal container REST success and error response reads using shared provider HTTP readers.
2026-06-28 20:53:58 -07:00
Alix-007
5f86c3a90f fix(qa-matrix): bound homeserver response reads
Bounds Matrix QA homeserver JSON and media upload response reads with existing response-limit helpers.
2026-06-28 20:53:53 -07:00
wangmiao0668000666
e4e4b0161f fix(mistral): bound streaming response bodies
Bounds Mistral SDK response streams at 16 MiB using the existing streaming byte guard.
2026-06-28 20:53:49 -07:00
Josh Avant
7c47904bb4 Stage managed inbound media for runner access (#97647) 2026-06-28 22:40:42 -05:00
llagy009
6299b679c0 fix(tlon): truncate approval message preview on UTF-16 boundary (#97599)
* fix(tlon): truncate approval message preview on UTF-16 boundary

formatApprovalRequest called truncate() with raw .slice() before the
trailing ellipsis. A Tlon ship display name or message preview whose
emoji landed on the 100-character preview cap was split mid-surrogate
pair, emitting a lone surrogate in the owner notification. Use
sliceUtf16Safe so the truncation always falls on a code-point boundary.

* fix(tlon): guard all three messagePreview UTF-16 truncation sites

The prior commit only guarded the formatter (truncate in approval.ts).
The root-cause sites are in monitor/index.ts where PendingApproval is
constructed:

  messagePreview: rawText.slice(0, 100),     // channel mention path
  messagePreview: messageText.slice(0, 100), // DM path

An emoji whose high surrogate falls at position 99 was sliced mid-pair,
storing a lone \uD83D in the persistent PendingApproval before the
formatter ever ran.

Fix: replace both production sites with sliceUtf16Safe(), and also
guard the createPendingApproval() constructor itself so any future
caller that passes an untruncated preview is automatically safe.

Add regression tests that drive the full
createPendingApproval -> messagePreview -> formatApprovalRequest chain
for both the DM and channel paths with an emoji placed exactly at the
100-unit boundary.

* fix(tlon): truncate approval message preview on UTF-16 boundary

* fix(clownfish): repair validation for live-pr-inventory-20260629T032026-001 (2)

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-28 20:40:32 -07:00
cxbAsDev
d5aca1d6d2 fix(xai): bound OAuth response reads to prevent OOM (#97615)
Replace unbounded response.text() in readResponseBody and
response.json() in the device-code polling loop with
readResponseWithLimit (16 MiB cap).
2026-06-28 20:26:20 -07:00
cxbAsDev
615558f6fb fix(provider-usage): bound Anthropic usage error response reads to prevent OOM (#97614)
Replace unbounded res.json() with readProviderJsonResponse in the
fetchClaudeUsage error path to cap error body reads at 16 MiB.
2026-06-28 20:26:11 -07:00
liuhao1024
f6115dd5fe fix(failover): allow model_not_found to trigger fallback chain when configured (#97571)
Remove model_not_found from the shouldEscalateRetryLimit exclusion list
so that configured fallback models are attempted when the primary model
is decommissioned by the provider. Previously, model_not_found was
treated as terminal, silently defeating the fallback chain for the
decommission case.

Fixes #97564
2026-06-28 20:24:23 -07:00
Colin Johnson
59d8462b1d fix(macos): open dashboard when Dock or Finder relaunches app (#97637)
* fix(macos): open dashboard on Dock reopen

* fix(macos): preserve visible-window Dock reopen

* style(macos): satisfy deep link switch formatting
2026-06-28 20:24:15 -07:00
Alix-007
2001b15f5b fix(google-meet): bound Drive document export reads to prevent OOM (#97620)
* fix(google-meet): bound Drive document export reads to prevent OOM

* test(google-meet): return full guarded fetch result

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-28 19:57:01 -07:00
Alex Knight
1f0c6a66a6 fix(plugins): plugin loggers drop writes after the log level is raised at runtime (#97617)
* fix(plugins): plugin loggers drop writes after the log level is raised at runtime

The plugin runtime logging facade captured a single tslog child logger per
getChildLogger() call. tslog snapshots a sublogger's min level at creation, so a
long-lived plugin logger (e.g. a channel monitor that runs for the whole gateway
session) kept dropping debug/verbose writes after the log level was raised at
runtime, even though shouldLogVerbose()/isFileLogLevelEnabled() reported the new
level. This made channels like Mattermost go dark while core subsystem loggers
(which re-resolve per emit) kept logging.

Resolve the child logger per call so it always reflects the current level, with a
cheap isFileLogLevelEnabled pre-gate (skipped for explicit overrides) to avoid
building a sublogger when the level is disabled. Fixes every channel that holds a
long-lived monitor logger (mattermost, matrix, msteams, irc, nextcloud-talk) at
the facade boundary with no plugin-code changes.

* test(plugins): type runtime log-level mock

---------

Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-28 19:55:37 -07:00
xydigit-sj
00c9ac55d6 fix(secrets): skip PLAINTEXT_FOUND for known non-secret apiKey markers (#97622)
Exclude models.providers.*.apiKey values that match isNonSecretApiKeyMarker
(e.g., lmstudio-local, ollama-local) from secrets audit plaintext warnings.
Regression test covers marker bypass and real-key flagging.

Closes #89233
2026-06-28 19:49:05 -07:00
Dallin Romney
a202dd0faf test: link mcp gateway transport coverage (#97609) 2026-06-28 19:20:15 -07:00
NIO
245257238b fix(agents): keep missing external channel providers in agents list 2026-06-28 19:19:58 -07:00
吴杨帆
63fe5c7402 fix(ui): scroll to cron run history 2026-06-28 19:18:26 -07:00
zhangqueping
15fc881281 fix(cli): clarify safe restart bounded-then-force behavior in help and docs 2026-06-28 19:18:13 -07:00
Wynne668
32d117c68b fix(control-ui): persist Set Default agent through config save 2026-06-28 19:15:27 -07:00
Yuval Dinodia
bbc4c56a6d fix(config): name openai-chatgpt-responses for the removed openai-codex-responses api id 2026-06-28 19:15:19 -07:00
liuhao1024
6dccb61e56 fix(memory): align session file counter denominator with indexer filter (fixes #77338) 2026-06-28 19:14:27 -07:00
linhongkuan
6d658c70ea fix(terminal-core): tighten docs link URL detection 2026-06-28 19:14:18 -07:00
llagy009
4109755592 fix(discord): truncate model picker button labels on UTF-16 boundary 2026-06-28 19:08:49 -07:00
llagy009
352f47f888 fix(imessage): coalesce merged text on UTF-16 code-point boundary 2026-06-28 19:08:39 -07:00
llagy009
1841c4caf5 fix(feishu): truncate comment prompt text on UTF-16 boundary 2026-06-28 19:07:11 -07:00
Dallin Romney
938855082a fix(reply): clear 'model unavailable' reply + correct operator hint for retired runtime models (#97611)
* fix(models): don't advise models.providers[] registration for runtime-bound models

When an agent's configured model is bound to an agent runtime (e.g. the
"codex" runtime, whose catalog comes from the OpenAI ChatGPT-account
app-server), and that model id is no longer offered by the runtime, model
resolution fails with "Unknown model: <provider>/<model>". The appended hint
told users to register the model in models.providers[].models[].

For runtime-owned models that advice is misleading: adding the registration
makes resolution "succeed" only for the request to be rejected later by the
provider — e.g. OpenAI returns 400 "model is not supported when using Codex
with a ChatGPT account" once a model id such as gpt-5.3-codex is deprecated.

Detect the agentRuntime binding on the configured agents.defaults.models entry
and instead point the user at the runtime's live catalog (openclaw models list
--provider <id>) and at switching the configured default to an available model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reply): show a clear "model unavailable" reply instead of generic failure

When a configured model is retired/renamed by the provider, model resolution
fails (run.ts throws a typed FailoverError with reason "model_not_found") and
the agent runner falls back to the generic "Something went wrong … use /new"
reply. That copy is actively misleading for this failure: retrying or starting
a new session can never help, because the model id itself must be changed in
config. Users on a deprecated model (e.g. gpt-5.3-codex on a Codex ChatGPT
account) just see the generic message on every message and on /new.

Classify this failure into a dedicated user-facing reply that explains the
model is unavailable and points at the config. Detection is structural — it
keys off the typed FailoverError reason, not provider error text — so it stays
robust as provider wording changes; free-text rejections without a typed reason
remain the responsibility of the failover layer that owns error classification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 19:02:21 -07:00
moguangyu5-design
b28fcfe843 fix(telegram): fall back to plain text when rich message entity validation fails (#96642)
When Telegram rejects a rich message with RICH_MESSAGE_*_INVALID
(e.g., RICH_MESSAGE_EMAIL_INVALID on /status replies), the delivery
path now falls back to a plain text sendMessage instead of dropping
the reply.

Fixes #96363
2026-06-28 19:00:07 -07:00
zw-xysk
7ae52dc56e fix(model-resolver): use numeric-aware version comparison for model alias resolution 2026-06-28 18:55:25 -07:00
dwc1997
bf83ea1394 test(agents): add unit tests for exec output rendering helpers 2026-06-28 18:55:15 -07:00
Yufeng He
19433638f8 fix(sessions): keep sibling dirs that share the home prefix unshortened in tool path display 2026-06-28 18:54:32 -07:00
llagy009
46434f0c71 fix(telegram): reject surrogate/out-of-range numeric HTML entities 2026-06-28 18:54:24 -07:00
ly-wang19
2852fa7e35 fix(discord): only unwrap a single emphasis span from thread titles, not multi-span 2026-06-28 18:53:37 -07:00
NIO
a82cff8892 fix(ollama): bound cloud-auth 401 JSON response reads 2026-06-28 18:53:28 -07:00
Dallin Romney
39e1be080c feat(slack): support alternate Web API roots (#97154)
* Allow Slack to target alternate Web API roots

* Protect Slack API URL routing

* Simplify Slack API URL routing

* Use env-only Slack API root routing

* Remove Slack client option alias

* Keep Slack API URL dotenv test inline

* Remove leftover Slack PR churn

* Block workspace Slack API URL dotenv

* Preserve Slack proxy HTTPS protocol

* Keep Slack option resolution explicit

* Remove Slack probe formatting diff

* fix(slack): preserve explicit API root precedence

* fix(slack): narrow cached write client options
2026-06-28 18:52:37 -07:00
linhongkuan
8f9beb7766 fix(reply): sanitize explicit reply directive ids 2026-06-28 18:51:38 -07:00
QiuYuang
820fadc3f2 fix(template): resolve variable shadowing in export-html template 2026-06-28 18:51:29 -07:00
liuhao1024
b1ef12055e fix(agents): preserve compactionSummary in limitHistoryTurns (fixes #97590) (AI-assisted) 2026-06-28 18:51:19 -07:00
evan-YM
4a4657a182 fix(ui): remove redundant selectedLabel rendering in Talk settings (#96915) (#96925)
The renderNativeTalkSelect function was rendering an extra .agent-chat__talk-select-label
span element for Voice and Sensitivity fields, causing misalignment with the Model field.

Changes:
- Remove selectedLabel parameter from renderNativeTalkSelect function signature
- Remove the conditional rendering of .agent-chat__talk-select-label span
- Clean up the selectedLabel argument in renderRealtimeTalkOptions

This ensures all three fields (Voice, Model, Sensitivity) have identical HTML structure
(label span + input/select), resulting in perfect visual alignment.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 18:40:45 -07:00
zw-xysk
4e7992cc9b fix(feishu): keep top-level appSecret SecretRef active for the implicit default account (#96965)
When a Feishu channel has top-level appId/appSecret using SecretRef
format and sub-accounts with their own inline appSecret, the secrets
resolver marks the top-level SecretRef as inactive because
isBaseFieldActiveForChannelSurface only checks whether any explicit
account inherits the field.

Feishu account listing always creates an implicit default account from
top-level credentials.  The fix detects this implicit default account
and keeps the top-level appSecret active accordingly, without changing
the shared channel secret helper semantics for other channels.

Fixes #96929

Signed-off-by: 赵旺0668001248 <0668001248@duomai.com>
2026-06-28 18:40:41 -07:00
linhongkuan
69b0604f31 fix(telegram): expose sender bot status in context (#96810)
* fix(telegram): expose sender bot status in context

* chore: retrigger PR checks

---------

Co-authored-by: lin-hongkuan <lin-hongkuan@users.noreply.github.com>
2026-06-28 18:40:06 -07:00
David
d4441f6fe4 fix(compaction): keep accepted sessions_spawn results out of tool-failure summaries (#96842)
Accepted sessions_spawn launches can be persisted as a toolResult with isError:true while the payload carries status=accepted. The compaction safeguard collected every isError toolResult, so normal accepted subagent launches surfaced as repeated '## Tool Failures' lines in user-visible summaries. collectToolFailures now skips results whose toolName is sessions_spawn and whose payload normalizes as an accepted child spawn, mirroring the observer's existing detection; this covers legacy transcripts too. Genuinely failed spawns (status=error/forbidden) and non-spawn tools are still reported.
2026-06-28 18:40:02 -07:00
David
b3ff64145e fix(codex): classify accepted/created/updated dynamic-tool statuses as success (#96856)
isCodexToolResultError fail-closes every tool-result status not in its
non-error allowlist, but the allowlist omitted several success statuses
emitted by OpenClaw tools that are exposed to codex agents:

- sessions_spawn accepted launches  -> details.status "accepted"
- create_goal / update_goal results -> details.status "created" / "updated"

So a successful accepted spawn (#96833), and successful goal create/update,
were classified as errors: reported to codex as success: false (mapped to a
Failed item status) and persisted on the transcript as isError: true. This
adds those statuses to the allowlist alongside their sibling success statuses
(completed/recorded/started/running). Genuinely failed or forbidden results
(status "error"/"forbidden") stay fail-closed.

Adds regression tests: accepted spawn and created/updated goal results are
reported as successful dynamic tool calls; a forbidden spawn still fails.
2026-06-28 18:37:00 -07:00
Harjoth Khara
31b531e791 fix(feishu): sanitize identity emoji in card headers (#96587)
* fix(feishu): sanitize identity emoji in card headers

* test(feishu): avoid env-key identity header fixture
2026-06-28 18:36:00 -07:00
dwc1997
0635a8c1a8 test(runtime): add unit tests for terminal runtime helpers (#96736)
Add unit tests for createNonExitingRuntime and writeRuntimeJson
functions in src/runtime.ts to verify runtime behavior.

Tests cover:
- createNonExitingRuntime returns runtime with exit function
- exit function throws error with code
- writeRuntimeJson writes JSON using writeJson when available
- writeRuntimeJson writes JSON using log when writeJson not available
- uses custom space parameter
- handles zero space parameter
2026-06-28 18:35:56 -07:00
Moeed Ahmed
a9eb0d7e9c Fix ACP manual-spawn task tracking (#97131)
Co-authored-by: Moeed Ahmed <5780040+moeedahmed@users.noreply.github.com>
2026-06-28 18:33:04 -07:00
liuhao1024
9202dbb1b6 fix(llm): coerce stringified JSON arrays/objects in tool argument validation (fixes #96916) (AI-assisted) (#96922)
* fix(llm): coerce stringified JSON arrays/objects in tool argument validation

When LLMs serialize array or object tool parameters as JSON strings
(e.g. tags: '["test","debug"]' instead of tags: ["test","debug"]),
validateToolArguments now attempts JSON.parse coercion before
rejecting the value. This mirrors the existing numeric string
coercion path and fixes MCP tool calls from providers like MiMo,
Ollama, and others that stringify complex parameters.

Fixes #96916

* fix(llm): bound JSON.parse size for schema-gated array/object coercion

Add MAX_JSON_COERCE_LENGTH (64KB) guard before JSON.parse in the array
and object coercion branches. Oversized stringified arguments are left
for normal validation to reject rather than synchronously parsed.

Addresses Codex review finding: unbounded JSON.parse on model-controlled
tool arguments could block the event loop or spike memory.
2026-06-28 18:32:59 -07:00
slammajamma28
68ad8dacc0 fix(docs): Fix formatting on permissions for Discord bot (#97584)
* Fix required formatting text permissions for Discord bot

* remove whitespace
2026-06-28 18:30:36 -07:00
Dallin Romney
4b8a0a8ecf Migrate Tool Search gateway E2E into QA Lab flow (#97478)
* test: migrate tool search gateway to QA flow

* test: use built SDK in tool search QA fixture

* test: fix tool search QA fixture lint

* test: gate tool search QA flow to mock provider

* Share QA Lab fixture utilities

* Tighten QA fixture helper defaults

* test: gate tool search QA flow mode
2026-06-28 18:16:15 -07:00
Stellar鱼
4b60e8bed4 fix(exec): expose termination metadata in tool details (#89104) 2026-06-28 18:16:01 -07:00
Brian Potter
cd31cbcd17 fix(memory-core): don't run the LLM reranker in vsearch/search modes (#88887)
vsearch/search are documented as vector/lexical-only modes, but
runQmdSearchViaMcporter omitted `rerank` from the query tool callArgs,
so QMD's query tool (which defaults rerank:true) ran the LLM reranker
anyway. Pass rerank:false for those modes; full "query" mode keeps it.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 18:11:03 -07:00
Masato Hoshino
be0c40bad2 fix(commitments): preserve extraction batch on transient failure (#89817)
A drained extraction batch is spliced off the queue before the extractor
runs. On a non-terminal failure the batch was never restored, so those
items were silently lost and never retried. Restore the batch to the
front of the queue (original order) on non-terminal errors and rethrow so
the caller still logs; terminal model/auth errors keep the existing
cooldown drop/stop behavior. Also ensure the single-slot debounce
schedules a drain from the overflow branch, so a queue left full by a
restored batch still gets retried instead of being stuck.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 18:10:41 -07:00
Martin Kessler
ac6f249de1 test(codex): cover binds without model overrides (#89535) 2026-06-28 18:09:51 -07:00