Commit Graph

64071 Commits

Author SHA1 Message Date
Gio Della-Libera
f466ebc00c policy: classify doctor fix recommendations 2026-07-04 19:34:17 -07:00
Amir
1efc7270cd fix(cli): include aliases in shell completion (#99419)
* fix(cli): shell completion omitted command aliases like capability, chat, and cron create

* fix(cli): route the dead exec-approvals root alias and single-source alias path expansion

* fix(cli): complete nested aliases in Bash

Co-authored-by: Jack-dev-ops <chen.zegui@xydigit.com>

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Jack-dev-ops <chen.zegui@xydigit.com>
2026-07-04 19:33:00 -07:00
Ayaan Zaidi
eb2f9bece7 fix(agents): persist spill metadata for elision recovery
Preserve fullOutputPath plus partial-spill metadata when oversized tool-result details are summarized for persistence. This keeps aggregate elision from relabeling capped or source-truncated web_fetch spill files as complete after reload.
2026-07-04 19:26:16 -07:00
Ayaan Zaidi
235f18def5 fix(agents): spill truncated web fetch output
Write truncated web_fetch extracted content to owner-only private temp files using the shared Full output footer contract. Spills use the wrapped untrusted-content form, cap recoverable content at 2,000,000 chars, and label capped or source-truncated spills as partial instead of full output.
2026-07-04 19:26:16 -07:00
Ayaan Zaidi
ad826faf0d fix(agents): preserve spill pointers through tool-result elision
Keep aggregate elision recoverable by preserving existing spill pointers only when the original model-visible footer already disclosed the path. This commit also keeps partial-spill markers honest, handles JSON-escaped footers, and resolves full-clear markers from the original tool-result message after partial aggregate shrinking.
2026-07-04 19:26:16 -07:00
Peter Steinberger
adf25f853c fix(ui): add chat transcript top spacing (#100144)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 19:24:25 -07:00
NIO
b4f09fe7fa fix(qa-lab): bound suite runtime gateway JSON response reads (#99165)
Summary:
- The PR replaces QA Lab suite gateway `fetchJson` success-path `response.json()` with shared `readProviderJsonResponse` and adds an oversized-response regression test.
- PR surface: Source +1, Tests +33. Total +34 across 2 files.
- Reproducibility: yes. Current main still has the unbounded `response.json()` success path in `fetchJson`, an ... l proof for oversized streamed bodies, early cancellation, normal parsing, and the focused regression test.

Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(scripts): satisfy oxlint in qa-lab suite gateway bound proof
- PR branch already contained follow-up commit before automerge: fix(qa-lab): bound suite runtime gateway JSON response reads
- PR branch already contained follow-up commit before automerge: chore: drop local proof script from qa-lab gateway bound PR

Validation:
- ClawSweeper review passed for head 8c0eb49fcb.
- Required merge gates passed before the squash merge.

Prepared head SHA: 8c0eb49fcb
Review: https://github.com/openclaw/openclaw/pull/99165#issuecomment-4868175663

Co-authored-by: NIO <nocodet@mail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
2026-07-05 02:16:25 +00:00
Narahari Raghava
7d3cfa85dc fix(infra): roll session warning durations across unit boundaries (#100096)
* fix(infra): formatDuration rolls over near-boundary values to the next unit

The raw float was checked against the boundary before rounding, so values
like 59.5s, 59m30s, and 23h59m30s rounded up to "60 seconds", "60 minutes",
and "24 hours" in session maintenance warning messages instead of "1 minute",
"1 hour", and "1 day". Round first, then check the unit boundary.

Closes #99978

* fix(infra): fix formatDuration progressive rollover in session maintenance warning

Round seconds first, then promote to the next unit only when the
rounded lower unit reaches its overflow threshold (60s->min, 60m->hr,
24h->day). The previous approach compared raw milliseconds against the
unit boundary before rounding, causing half-unit values like 30s, 30m,
and 12h to promote one unit too early.

Closes #99978

* test(infra): expose formatDuration via testing export for direct verification

* ci: retrigger checks

* ci: retrigger checks

* test(infra): keep duration formatter private

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-04 19:02:30 -07:00
Vincent Koc
48d12dcc8d chore(plugin-sdk): refresh API baseline hash 2026-07-05 03:54:37 +02:00
Peter Steinberger
31cf660319 fix(chat): hide duplicate channel delivery mirrors (#100136) 2026-07-04 21:53:32 -04:00
Peter Steinberger
ea5d4b7943 chore: enable array fill lint rule (#100122)
* chore: enable array fill lint rule

* chore: enable array fill lint rule

* chore: enable array fill lint rule
2026-07-04 21:51:08 -04:00
qingminlong
9b78ec8d6f fix: keep subagent truncation within max length (#100013) 2026-07-04 18:48:23 -07:00
WhatsSkiLL
b550c829b2 [AI-assisted] fix(android): polish home overview layout (#100059)
* fix(android): polish home overview layout

* chore(android): refresh native i18n inventory

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
2026-07-04 21:42:36 -04:00
Yuya Hirayama
fe8234621e Fail closed when Slack mention detection is unavailable (#91584)
* fix(slack): fail closed when mention detection is unavailable

* fix(slack): coordinate app mention retry history

* fix(slack): reject user-token mention identity

* fix(slack): reject user-token mention identity

---------

Co-authored-by: OpenClaw Agent <openclaw-agent@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 21:36:53 -04:00
Peter Steinberger
1b8d837674 fix(tui): preserve queued prompt lifecycle (#100123)
Allow busy TUI sessions to forward prompts into the configured queue while
keeping queued-turn admission, cancellation, restart, and transcript ownership
consistent across the TUI, Gateway, and followup queue.

Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-07-04 21:15:28 -04:00
moguangyu5-design
3dff585de6 fix(agents): use CJK-aware token estimation for tool results (#95447)
* fix(agents): use CJK-aware token estimation for tool results

Preserve the conservative 2 chars/token ratio for non-CJK tool results,
while using the accurate 4 chars/token ratio for CJK-heavy tool results.
This avoids false context-overflow errors for CJK content without changing
behavior for Latin/ASCII tool results.

- Add estimateCjkRatio() helper to cjk-chars.ts
- Choose tool-result chars-per-token based on CJK ratio (threshold 0.5)
- Add regression tests for CJK, mixed, and non-CJK tool results

* fix(agents): cover JSON and fallback payloads in CJK ratio pass

* test(agents): fix type cast for non-serializable tool-result regression

* fix(agents): make CJK tool-result estimates monotonic

---------

Co-authored-by: moguangyu5-design <moguangyu5-design@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-04 18:15:24 -07:00
Peter Steinberger
1437f79d0c feat(ui): adopt shared libterminal browser runtime (#100128) 2026-07-04 21:03:10 -04:00
Gio Della-Libera
7bb686c140 Doctor: expose systemd linger findings (#97514)
Expose an opt-in Doctor lint finding for Linux Gateway hosts where a loaded user-level systemd gateway unit has systemd lingering disabled.\n\nValidation:\n- Targeted Doctor health contribution tests passed locally.\n- Exact-head hosted checks passed on 65ec5a0acf, including QA Smoke CI, Real behavior proof, security/CodeQL, check-shrinkwrap, and selected CI shards.\n- Crabbox Azure proof exercised a loaded user systemd gateway unit with Linger=no and observed the expected lint warning.\n\nCo-authored-by: giodl73-repo <166990625+giodl73-repo@users.noreply.github.com>
2026-07-04 17:59:41 -07:00
Vincent Koc
2e7ffca8ff fix(core): preserve UTF-8 byte truncation boundaries 2026-07-04 17:48:21 -07:00
Peter Steinberger
aaaa8030bf docs(onboard): fix stale signal-cli, daemon runtime, and allowlist claims in onboarding reference 2026-07-05 01:46:28 +01:00
Peter Steinberger
b3a74ccc3a docs(acp): correct permission-prompt error class in troubleshooting table
The non-interactive permission failure surfaces as acpx's
PermissionPromptUnavailableError, not AcpRuntimeError; acpx 0.11.2 throws
it unwrapped (isGenericInternalAcpErrorMessage only matches "Internal
error"). Matches the corrected fact in the acp-agents-setup rewrite.

Pre-commit hook bypassed with formatting proof: repo oxfmt + Mintlify
accordion repair already run on the file (worktree has no node_modules).
2026-07-05 01:44:42 +01:00
Peter Steinberger
d460635185 fix(browser): point Playwright 501 error at existing docs anchor 2026-07-05 01:44:19 +01:00
Peter Steinberger
73fc0f5c5f fix(channels): expose inbound media download failures [AI-assisted] (#100119)
* fix(channels): expose inbound media download failures

* fix(msteams): correlate attachment references
2026-07-04 20:28:52 -04:00
Narahari Raghava
161c4581a7 fix(gateway): truncateCloseReason drops partial UTF-8 code point instead of emitting mojibake (#100047)
* fix(gateway): truncateCloseReason drops partial UTF-8 code point instead of emitting mojibake

Buffer.subarray at a raw byte offset can cut inside a multi-byte UTF-8
sequence. Node decodes the dangling continuation bytes as U+FFFD (3 bytes
each), so the re-encoded result can exceed the intended maxBytes cap —
violating the RFC 6455 close-reason size contract and surfacing garbled
text to clients.

Back up from the cut point to the nearest UTF-8 sequence start before
slicing (UTF-8 continuation bytes match 10xxxxxx; skip them).

Closes #99976

* fix(lint): remove unnecessary non-null assertion on Buffer index

* ci: retrigger checks
2026-07-04 17:25:30 -07:00
Vincent Koc
890f4efc88 fix(qa-channel): handle metadata-free final replies
Fix qa-channel final reply preview delivery when a harness or plugin path calls deliver without dispatcher metadata. Verified with remote Testbox proof plus hosted PR checks.
2026-07-04 17:23:52 -07:00
Hana Chang
4ec7842be0 feat(slack): add ignoreOtherMentions channel config (#53467)
* feat(slack): add ignoreOtherMentions channel config

Mirrors the existing Discord `ignoreOtherMentions` option for Slack
channels. When set on a channel entry, drop channel/group/MPIM messages
that mention another user or subteam but not this bot — the inverse of
`requireMention`. Useful in busy channels where the bot would otherwise
reply to side conversations.

Implementation lives in `prepareSlackMessage` right after the
`allowBots: "mentions"` bot-drop gate and before the `shouldRequireMention`
non-mention drop, so it integrates with the new `messageIngress` ingress
pipeline. The gate is conditional on `canDetectMention` (botUserId
resolvable via `auth.test` or explicit mention regexes configured) to
avoid false drops when we have no reliable way to tell bot vs non-bot
mentions apart.

Slack implicit mentions (thread participation) are intentionally NOT
respected here — they fire for every message in a bot-participated
thread, so honoring them would defeat the feature in any active thread.
The gate matches on `wasMentioned` (explicit) and `hasAnyMention`, with
the existing `shouldBypassMention` override (e.g. authorized commands)
also respected.

Includes config types, zod schema, channel-config resolution,
prepare-message implementation, full test coverage in
`prepare.test.ts`, regenerated channel + docs baselines, and Slack
docs entry.

* refactor(slack): harden other-mention filtering

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 20:08:14 -04:00
Rohang2005
03fe813d1e fix(slack): forward per-agent identity overlay on heartbeat and runtimeSend (#84297) (#84335)
* fix(slack): preserve agent identity on heartbeat sends

Co-authored-by: Rohang2005 <rohan.ganesh05@gmail.com>

* fix(slack): preserve identity when custom icons fail

* fix(slack): reuse accepted identity across chunks

* fix(slack): narrow identity fallback input

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-04 20:05:47 -04:00
TwinsLee
568237b3ab fix(feishu): emit non-empty value schema for bitable write tools (#94547) (#94990)
Type.Record(Type.String(), Type.Any()) serializes via TypeBox to an empty nested value schema (patternProperties: { "^.*$": {} }). AWS Bedrock's strict tool-schema validation rejects the empty sub-schema, breaking all agent turns for Bedrock-backed Anthropic users with Feishu bitable tools enabled.

Replace the three affected free-form field maps (create_record, update_record, create_field) with an explicit non-empty FlexibleFieldValue value schema that still accepts any JSON value. Type.Unknown() is avoided because it also serializes to an empty schema. Adds regression coverage asserting the emitted value schema is non-empty.

Co-authored-by: TwinsLee <1460694+TwinsLee@users.noreply.github.com>
2026-07-04 17:05:32 -07:00
Dallin Romney
bfffa950d7 refactor(plugin-sdk): consolidate tool result helpers (#99740)
* refactor(plugin-sdk): consolidate tool result helpers

* docs(plugin-sdk): tighten tool result guidance

* refactor(feishu): use tool results directly
2026-07-04 16:50:44 -07:00
Dallin Romney
c2fc7aa28a refactor: consolidate exact keyed async queues (#99691)
* refactor: consolidate keyed async queues

* chore: refresh merge-ref CI

* refactor: encapsulate keyed queue ownership
2026-07-04 16:45:07 -07:00
Peter Steinberger
7608d38597 improve(ui): flatten chat tool-call rows into scannable list (#99763)
Tool calls in Control UI chat rendered as triple-nested cards: activity
group card + tool-shell bubble chrome + gradient summary pill with a
0 8px 22px drop shadow. Collapsed rows now render as flat single-line
rows with ellipsis, the activity group uses a flat header plus a left
rule, and expanded detail keeps soft tinted blocks without card chrome.
Also deletes the dead legacy .chat-tool-card__details/__output CSS and
the unused renderToolCardSidebar path with its never-taken
renderToolDataBlock branches.

Closes #99760
2026-07-04 19:42:59 -04:00
Vincent Koc
3d64efbd3d test(ui): stabilize Control UI suite routing
Keep moved Control UI browser layout tests routed in both UI Vitest configs and stabilize chat suite-order assertions. Verified with Testbox UI proof and changed gate; final PR CI remains the merge gate.
2026-07-04 16:38:36 -07:00
Dallin Romney
194dd6fe50 refactor(security): consolidate secret primitives (#99746)
* refactor(security): consolidate secret primitives

* fix(plugin-sdk): align secret display metadata

* chore(plugin-sdk): refresh API baseline after rebase

* refactor(security): trim secret primitive consolidation
2026-07-04 16:38:13 -07:00
qingminlong
3adfaf0394 fix: detect localized Windows netstat listeners (#100012)
* fix: parse localized Windows netstat listeners

* fix: share Windows netstat PID fallback

* test: relax native command QA timeout

* test: wait for native stop cleanup before recovery

* fix(windows): harden localized netstat parsing

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-04 16:35:29 -07:00
Dallin Romney
dc3b5df684 refactor(types): remove redundant local aliases (#100061)
* refactor(models): remove redundant generation model ref alias

* refactor(types): remove redundant local aliases

* refactor(types): preserve shipped model ref type
2026-07-04 16:34:47 -07:00
Dallin Romney
cf14b27d81 refactor: consolidate safe json parsing (#99688) 2026-07-04 16:33:27 -07:00
Ayaan Zaidi
4682364fa6 fix(agents): compact on aggregate tool-result pressure 2026-07-04 16:21:08 -07:00
Ayaan Zaidi
168a4890bb fix(agents): scale aggregate tool-result budget by context 2026-07-04 16:21:08 -07:00
Marvinthebored
6445a0632d feat(cli): render claude CLI native thinking with /reasoning gating
The claude-cli (claude-stdio) live-session backend emits native
reasoning on stream-json (`thinking_delta` + a snapshot `thinking`
block), but the CLI parser had no thinking handling at all, so it was
silently dropped on every surface in every /reasoning mode.

- cli-output.ts: parse thinking_delta/snapshot into stream:"thinking"
  with replace-style per-content-block-index dedupe
  (assembleThinkingTextByIndex), robust to tool-interleaved multi-block
  turns (snapshot replaces per-index rather than assuming a streamed
  prefix). signature_delta/redacted_thinking stay skipped.
- agent-runner-cli-dispatch.ts: bridge stream:"thinking" into
  onReasoningStream via a new createReasoningTextBridge (mirrors the
  existing assistant-text bridge), replacing the old
  assistant-text-as-reasoning heuristic. Track the final reasoning
  snapshot and, when present, prepend a durable
  `{text, isReasoning: true}` payload before the answer — mirroring
  the embedded-runner durable reasoning payload
  (embedded-agent-runner/run/payloads.ts).
- agent-runner-execution.ts: thread isReasoningSnapshot through to
  onReasoningStream, still passing requiresReasoningProgressOptIn:true
  so CLI reasoning rides the exact same channel gates as embedded
  reasoning (Discord/Telegram): /reasoning off -> nothing on any
  surface, stream -> window preview only, on -> durable payload too.
  The bridge is suppressed under the same conditions as the assistant
  bridge (e.g. silentExpected follow-ups), so no durable payload is
  synthesized for turns that are expected to stay silent.

Supersedes this branch's prior commit (a straight port of
af7eb48e05's emit-always model, no gating and no durable mode) with
the above gated/durable design per product decision.

Also, in cli-output.ts: reset the per-content-block-index thinking
tracker on every new Anthropic message (message_start, or a fresh
top-level "assistant" snapshot's message.id) instead of leaving it
scoped to the whole CLI turn. Content-block indices restart at 0 per
Anthropic message, so a tool round-trip within one turn (message A:
thinking + tool_use; tool result fed back; message B: a fresh
message_start) was letting message A's stale index-0 thinking text
bleed into message B's index-0 delta.

And in agent-runner-cli-dispatch.ts: attach the durable reasoning
payload whenever any thinking was bridged, not only when the CLI also
produced a visible final answer, so a thinking-only turn (no visible
reply) doesn't silently drop its reasoning.

Round 2: the durable `{isReasoning: true}` payload synthesized above
was also reaching the QUEUED FOLLOW-UP delivery path
(followup-runner.ts -> resolveFollowupDeliveryPayloads) with no gate
at all, so a claude-cli queued follow-up with /reasoning off would
leak internal reasoning to the channel as an ordinary visible message.
resolveFollowupDeliveryPayloads (followup-delivery.ts) now takes a
reasoningPayloadsEnabled flag and drops isReasoning payloads unless
it is true; followup-runner.ts threads opts?.reasoningPayloadsEnabled
through at both call sites, from the same GetReplyOptions the direct
path already reads (dispatch-from-config.ts:2054). This makes the
queued-follow-up path apply the identical isReasoning/
reasoningPayloadsEnabled gate that direct dispatch already enforces
(dispatch-from-config.ts:3347, :3537) — no new mechanism, CLI
follow-ups now go through the exact same gate embedded follow-ups do.

Scope note: routeReply's own unconditional suppression of isReasoning
payloads on the origin-routing branch (route-reply.ts:131,
shouldSuppressReasoningPayload) is pre-existing, shared with the
embedded runner, and unchanged by this commit — that gate governs
whether a kept-and-routed reasoning payload is actually rendered on a
cross-channel queued follow-up, and is out of scope here. This commit
closes the leak (off -> never eligible on any path); it does not
change what happens to an eligible payload once it reaches routeReply.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-04 16:19:10 -07:00
github-actions[bot]
1c9e998d98 chore(ui): refresh control ui locales 2026-07-04 23:07:17 +00:00
Peter Steinberger
dd6bc2ec32 fix(ui): repair router refactor regressions (#100106) 2026-07-04 19:00:54 -04:00
Peter Steinberger
f5d446e483 chore(ui): translate terminal.detached across locales 2026-07-04 15:58:18 -07:00
Peter Steinberger
e57bcbca50 docs: fold terminal reattach into the hardened terminal docs (opt-in default) 2026-07-04 15:58:18 -07:00
Peter Steinberger
619fee1b4f fix(control-ui): never close live sessions from bulk teardown; reattach owns recovery 2026-07-04 15:58:18 -07:00
Peter Steinberger
2b89a9b14d docs(control-ui): document why teardown close RPCs cannot kill reattachable sessions 2026-07-04 15:58:18 -07:00
Peter Steinberger
ad6d55159a fix(control-ui): keep the terminal open preference across disconnects 2026-07-04 15:58:18 -07:00
Peter Steinberger
009d7354b8 fix(gateway): route terminal.attach/list/text through the lazy handler table 2026-07-04 15:58:18 -07:00
Peter Steinberger
b33f09b40d feat(control-ui): reattach terminal sessions after reload/reconnect with replay 2026-07-04 15:58:18 -07:00
Peter Steinberger
5938c7809a feat(gateway): terminal detach/reattach with output replay, terminal.list/text 2026-07-04 15:58:17 -07:00
Peter Steinberger
be8b5f6c4f fix(slack): preserve custom identity while streaming (#100084)
Use supported chat.startStream authorship and avoid edit-based previews when custom identity cannot stream.

Co-authored-by: MoerAI <friendnt@g.skku.edu>
2026-07-04 18:56:36 -04:00