Commit Graph

63088 Commits

Author SHA1 Message Date
Eva
bfc4e1dcb5 fix(telegram): restore active-run steering 2026-07-01 10:34:20 -07:00
Ayaan Zaidi
4895a00b94 fix(usage): tidy compact footer defaults 2026-07-01 09:59:37 -07:00
Peter Lindsey
2205bf9d24 test(usage): update default footer expectations 2026-07-01 09:59:37 -07:00
Peter Lindsey
f2b54d18d8 feat(usage): make built-in default footer Telegram-friendly
The built-in default footer (added in #92657) only defined a `discord`
surface. Telegram and every other surface fall through to `output.default`,
which was authored for a wide terminal: space-separated badges, a leading
space-less join onto the message body, and ↕️ token + 🗄 cache% segments.

On a narrow Telegram screen this wrapped at arbitrary spaces (often mid-meter
or between 📚 and its bar) and welded onto the end of the message text.

Make `default` read well on a phone:
- Leading \n so the footer sits on its own line below the body.
- Tight badges (no separators between model/flags/reasoning/fast).
- NBSP before "|" and 💰; 📚 glued hard to the meter so it can't wrap there.
- Single regular space after "|" as the only sanctioned wrap point.
- Drop ↕️ tokens and 🗄 cache% from the default — noise for most users
  (still available to anyone via a custom messages.usageTemplate).

Discord surface trimmed to match for consistency (keeps its -# dim header).
2026-07-01 09:59:37 -07:00
Peter Steinberger
db97bc1e4f test: isolate message tool unit plugin loading (#98701)
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
2026-07-01 17:35:29 +01:00
Ayaan Zaidi
a5e11c0083 fix(plugin-sdk): honor suppressReply across native commands 2026-07-01 09:09:45 -07:00
Alexander Chen
d616206c58 fix(types): remove unused PluginCommandSuppressReply export 2026-07-01 09:09:45 -07:00
Alexander Chen
a1553c96fd test(telegram): restore DM binding regression test alongside suppression test
ClawSweeper review flagged that the new suppressReply test replaced the
existing direct-message binding regression test instead of being added
beside it. Restore the DM binding test to maintain coverage for the
plugin command dispatch surface.
2026-07-01 09:09:45 -07:00
Alex
6f809195b1 docs(sdk): document suppressReply as Telegram-only in SDK overview 2026-07-01 09:09:45 -07:00
alexuser
20fcd4a39c fix(telegram): suppress fallback reply when plugin command returns suppressReply: true
Adds  to the  type so plugin
commands that handle their own transport delivery (e.g. via Telegram Bot API
directly with retry logic, IPv4 forcing, etc.) can signal the channel adapter
to skip the fallback reply.

When a plugin command handler returns , the Telegram
native command dispatcher now:
1. Cleans up any progress placeholder
2. Returns early without sending the "No response generated. Please try again." fallback

Includes detailed JSDoc for the new  flag explaining its use
for plugin commands that deliver their own responses via channel-native APIs.

Fixes #80756
2026-07-01 09:09:45 -07:00
Wynne668
d9d6108086 fix(agents): preserve UTF-16 tool summary truncation (#98644) 2026-07-01 08:56:40 -07:00
lizeyu
8c54704b77 fix(embedded-agent-runner): pump async streamFn through pumpStreamWithRecovery for mid-stream error recovery (#95430)
* fix(embedded-agent-runner): pump async streamFn through pumpStreamWithRecovery for mid-stream error recovery

When wrapEmbeddedAgentStreamFn returns an async function (e.g. when
authStorage or resolvedApiKey is present), the stream is a Promise that
resolves to AssistantMessageEventStreamLike. The old Promise branch in
wrapAnthropicStreamWithRecovery only handled Promise rejections via
.catch(), missing {type:"error"} events that arrive after the Promise
resolves — such as Anthropic thinking-signature replay rejections.

Now the Promise branch:
  - Awaits the resolved stream and runs pumpStreamWithRecovery on it,
    so mid-stream error events trigger thinking-signature recovery.
  - Handles Promise rejection via .then(onFulfilled, onRejected) with
    the same retryStreamWithoutThinking path used by the sync branch.
  - Returns a unified AssistantMessageEventStream (outer) identical to
    the non-Promise branch pattern.

Tests updated to match the new return type (outer stream + .result()
instead of a bare Promise).

Fixes #95429

* fix(anthropic): remove orphaned wrapRetryStreamWithRecoveryNotification

Function is dead code — the Promise-handling was inlined into
pumpStreamWithRecovery, leaving only a recursive self-call
with no external entry point.

* fix(embedded-agent-runner): add Promise-resolved-stream regression test

* fix: use createTestStreamErrorMessage for type-correct stream error in Promise-resolved test

* test(agents): cover async thinking stream recovery

---------

Co-authored-by: lzyyzznl <lzyyzznl@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 08:56:30 -07:00
solodmd
c914f896a2 fix(inworld): guard voices JSON.parse against malformed API response bodies (#98660) 2026-07-01 08:55:41 -07:00
Yuval Dinodia
adcfebc276 fix(codex): classify get_goal read statuses as successful dynamic tool calls (#98659)
isCodexToolResultError fail-closes any dynamic-tool result whose
details.status is absent from its non-error allowlist. get_goal returns
details.status "found" or "missing" (a successful read of the thread
goal, or its absence), neither of which was in the allowlist, so every
get_goal call was classified as an error: reported to codex as
success: false and persisted on the transcript with isError: true.

Sibling #96856 added the write-side goal statuses (created/updated) and
the accepted spawn status but missed the read-side get_goal statuses.
This adds found/missing alongside them. Genuinely failed statuses stay
fail-closed.
2026-07-01 08:36:38 -07:00
Yuval Dinodia
9541f4e8bd fix(memory-wiki): disambiguate the reserved index page stem for synthesis and ingest (#94326)
* fix(memory-wiki): disambiguate the reserved index page stem for synthesis and ingest

A create_synthesis or source ingest whose title slugifies to index was
written to the auto-generated <dir>/index.md. That file is the only
compiler-owned page filename: compile writes it per page group, and
compile/query/status exclude it from page scanning. So the stored fact
was both unretrievable and clobbered by the generated directory-index on
the next compile.

The collision only happens at the direct page-stem boundary: synthesis
(syntheses/<slug>.md) and ingest (sources/<slug>.md) build a bare
<dir>/<slug>.md path. The bridge, unsafe-local, and OKF callers compose
slugifyWikiSegment output into prefixed and hashed identities that can
never equal a bare index.md, and OKF already guards its own write path
via OKF_RESERVED_FILENAMES.

Add a dedicated slugifyWikiPageStem helper that escapes the reserved
index stem and route only the two direct page writers through it,
leaving slugifyWikiSegment output stable for the composed callers so
their persisted page ids and paths do not churn on upgrade. Only index
is reserved: the compiler never owns <dir>/log.md in these directories
(the wiki log lives at .openclaw-wiki/log.jsonl), so a Log title keeps
its existing direct path. Additive and deterministic, no migration.

* fix(memory-wiki): preserve reserved-page ids

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 08:35:13 -07:00
Wynne668
eb87566334 fix(qa-lab): bound convex broker response bodies (#98619) 2026-07-01 08:30:34 -07:00
zw-xysk
c1e88db10f fix(ui): add overflow-y:auto to workspace rail sections, prevent file list overflow (#98566) (#98611) 2026-07-01 08:28:45 -07:00
PollyBot13
ffd7d68687 fix: route iOS Talk fallback settings correctly (#98602) 2026-07-01 11:26:34 -04:00
wuqxuan
006f4e3ee8 fix: keep workspace rail file sections scrollable (#98646) 2026-07-01 08:24:35 -07:00
Peter Lee
85f7834852 fix(whatsapp): thread authDir through command authorization and owner bypass for LID JID resolution (#93379)
* fix(whatsapp): thread authDir through command authorization and owner bypass for LID JID resolution

WhatsApp group commands (/new, /stop) can be ignored when Baileys reports the sender as a LID JID (@lid) instead of a phone JID (@s.whatsapp.net). The resolveWhatsAppCommandAuthorized() and isOwnerSender() functions called getSelfIdentity/getSenderIdentity without passing authDir, so the LID-to-phone reverse mapping could not happen.

Fix: thread account.authDir through both command authorization and group owner-bypass identity resolution paths so that LID JIDs are properly resolved to phone E.164 identities before owner/allowlist checks.

* fix(whatsapp): replace deprecated top-level fields with admission overrides in LID JID test
2026-07-01 08:13:31 -07:00
Peter Lee
9fabdcf49d fix(feishu): send blocks as independent messages when blockStreaming is enabled (#94250)
* fix(feishu): send blocks as independent messages when blockStreaming is enabled

* fix(feishu): preserve mention targets on first independently sent block

* fix(feishu): route independent block sends through chunked text delivery

Route the independent block-send path through sendChunkedTextReply
instead of calling sendMessageFeishu directly, so the configured
Feishu textChunkLimit is honored for completed blocks. Preserve
mention targets only on the first emitted block chunk and keep
sentBlockText based on the original block text for duplicate-final
suppression.

Add regression test with a small textChunkLimit that verifies a
long block is split into chunked messages and mentions only appear
on the first chunk.

* fix(feishu): preserve block delivery target

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 08:12:13 -07:00
Yuval Dinodia
a5a8d992ae fix(claude-cli): return updatedInput in can_use_tool allow response (#98665)
Claude Code >= 2.1.156 tightened its PermissionResult schema so an
approved can_use_tool control_response allow branch must carry an
updatedInput record. The Claude live-session bridge answered with the
deprecated { behavior: "allow" } shape and no updatedInput, so the CLI
rejected every approval-gated native tool call (Bash, WebFetch, and
AskUserQuestion among them) with a ZodError before the tool ran.

Echo the tool input back unchanged as updatedInput on the allow branch,
matching the shape the Claude Code 2.1 binary expects. The deny branch
and all other behavior are unchanged.

Fixes #95171.
2026-07-01 08:11:38 -07:00
Super Zheng
0666423237 fix: media tools skip env-key provider plugins when auto-selecting models (#98623)
hasProviderAuthForTool/hasAuthForProvider now thread cfg and workspaceDir into resolveEnvApiKey, so provider plugins that authenticate via environment variables and are only discoverable with config are detected during image/video model auto-selection instead of being dropped as unconfigured.
2026-07-01 08:11:13 -07:00
RichChen01
808e8f09ba fix(cron): persist startup catch-up deferral ids in service state to prevent read-RPC clobber (#94022)
* fix(cron): persist startup catch-up deferral ids in service state to prevent read-RPC clobber

The startup overflow catch-up deferral (#93810) set deferred job
nextRunAtMs to a staggered slot, but the exemption was stored as a
local skipFutureRepairJobIds set threaded only into start()'s
maintenance recompute pass. Every other caller of
recomputeNextRunsForMaintenance — ensureLoadedForRead (list/status),
finalizeCompletedResults, empty-due tick, manual run preflight, and
releaseUnclaimedDueJobReservations — called maintenance recompute
without the skip set, causing shouldRepairFutureCronNextRunAtMs to
advance the deferred staggered slot to the job's natural next run,
dropping the missed run for a full period.

Fix: Move the exemption into CronServiceState as
pendingCatchupDeferralJobIds, populated by applyStartupCatchupOutcomes
where deferrals are assigned. recomputeNextRunsForMaintenance now
always checks this state-level set instead of a local parameter, and
clears each id once its staggered slot is reached (now >= nextRunAtMs).
This gives one canonical exemption path that covers all recompute
callers.

The now-redundant skipFutureRepairJobIds parameter is removed.

Fixes #93935

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(clownfish): address review for repair-94022-fresh-plan-20260618 (1)

* fix(cron): preserve agentTurn exempt + add stale-deferral cleanup + runtime proof

Address ClawSweeper review by:
1. Keeping the existing agentTurn deferred-slot exemption unchanged
   (shouldRepairFutureCronNextRunAtMs still returns false for agentTurn
   jobs with nextRunAtMs before the natural schedule).
2. Adding cleanup of stale pendingCatchupDeferralJobIds markers for
   jobs that no longer exist or are disabled.
3. Adding regression tests for pending startup catch-up deferral
   preservation and stale marker cleanup.
4. Adding standalone CLI runtime proof script demonstrating the fix.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add pendingCatchupDeferralJobIds to test-harness + remove unused import

- Add pendingCatchupDeferralJobIds to createMockCronStateForJobs to fix TS2741.
- Remove unused loadCronStore import from runtime proof script.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(cron): tighten startup catch-up deferral handling

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 08:04:31 -07:00
Onur Solmaz
530d576cc6 fix(agents): time out local streams without first event (#98525)
* fix(agents): time out streams without first event

* fix(agents): propagate first-event stream timeout

* fix(agents): abort streams on first-event timeout

* fix(agents): time out chatgpt websocket streams

* fix(agents): clamp first event stream timeouts

* fix(agents): keep first event timeout internal

* fix(agents): classify first event stream stalls as timeouts

* fix(agents): preserve provider first-event timeouts

* fix(agents): satisfy first-event timeout lint

* fix(agents): classify first-event stalls as idle timeouts

* test(tooling): include transcript store helper route
2026-07-01 23:01:46 +08:00
Fede Kamelhar
f35fbc898c fix(gateway): cap agentRunCache to prevent unbounded growth under run fan-out (#77973)
* fix(gateway): cap agentRunCache to prevent unbounded growth under run fan-out

Time-based prune only reclaims entries past the 10-minute TTL window; a burst
of run fan-out can add far more entries than the window reclaims, so the cache
could grow without bound between prunes. Add a FIFO entry cap (5000) enforced
on insert, mirroring the existing Discord REST entity-cache bound.

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

* test(gateway): preserve waited run snapshots under cache cap

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 07:48:58 -07:00
Peter Steinberger
909be7bcbc fix: validate message timeout before secret resolution (#98652)
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
2026-07-01 15:35:58 +01:00
sunlit-deng
ce4a259485 fix(openai): bound embedding batch file downloads (#98554)
* fix(openai): bound embedding batch file downloads

* fix(openai): bound batch output records

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 07:10:42 -07:00
huangjianxiong
8abd5d4071 fix(tlon): bound error response body reads to prevent OOM (#98496)
* fix(tlon): bound error response body reads to prevent OOM

Replace bare response.text() on non-ok paths with readResponseTextLimited
capped at 16 KiB so a hostile or misconfigured Urbit ship cannot force the
gateway to buffer an arbitrary-size error body into process memory.

Affected paths:
- pokeUrbitChannel (channel-ops.ts)
- channel.runtime.ts poke path
- sendSubscription (sse-client.ts)

* fix(tlon): fix lint issues in error-body-boundary test

- Remove unused beforeEach import
- Wrap if/else bodies in braces (curly)
- Use block body for Promise executors (no-promise-executor-return)

* fix(types): resolve pre-existing TS test type errors

- Fix TS2493 tuple type errors in server-cron-notifications and
  server-cron tests by adding explicit type annotations on mock.calls
- Fix TS2322 in anthropic.test.ts by adding as const to resource
  content block type

* chore: trigger CI
2026-07-01 06:57:21 -07:00
lizeyu
733de866eb fix(update-check): bound npm registry JSON response read to prevent OOM (#98508)
* fix(update-check): bound npm registry JSON response read to prevent OOM

- Replace unbounded res.json() with readProviderJsonResponse capped at 16 MiB
- Update test mock to use real Response instead of bare object
- Verified against live npm registry: openclaw update status --json returns latestVersion: 2026.6.11

* fix(update-check): add 4 boundary tests for bounded npm registry read

- Tests: oversized response >16 MiB, near-boundary success
- Tests: malformed JSON, non-200 status code
- All pass with the readProviderJsonResponse bounded reader

* chore: add real behavior proof script for bounded JSON reader

Adds a standalone proof script that starts a local HTTP server and
drives the bounded reader against it with real HTTP requests, showing:
- Normal responses (~1 MB) parse correctly
- Oversized responses (>20 MB) are rejected with a descriptive error
- Malformed JSON is caught
- RSS does not spike on oversized responses

Ref. https://github.com/openclaw/openclaw/pull/98508

* chore: remove PR-specific proof script before merge

The proof script was accepted by ClawSweeper (proof: sufficient,
rating: diamond lobster), but it duplicates repository logic and
fails the scripts lint lane. Removing it per review feedback.

The real behavior proof remains in the PR body.

Ref. https://github.com/openclaw/openclaw/pull/98508
2026-07-01 06:56:06 -07:00
JC
bd5bf4820a fix(cli): retry logs.tail after journal fallback in logs follow (#88159)
* fix(cli): retry logs.tail after journal fallback in logs follow

Rebase #88159 onto current main and keep systemd journal fallback temporary in follow mode. Preserve the journal cursor across repeated fallback outages, but retry logs.tail on the next loop so recovered Gateway RPC returns to normal log output.

This refresh also replaces the stale red checks-node-core-fast result from the old head with a current-head CI run.

* Keep log source metadata explicit

* ci: retrigger checks for PR #88159

* docs: clarify logs follow JSON source transitions

* fix(cli): keep journal logs responsive during recovery

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-01 06:55:11 -07:00
Wynne668
b6ad30625d fix(status): bound systemd service probes so status cannot hang on a wedged systemctl (#84698) (#94149)
* fix(status): bound systemd service probes so status cannot hang on a wedged systemctl (#84698)

* test(daemon): assert readRuntime receives the threaded status timeout opts (#84698)

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 06:52:14 -07:00
Wynne668
cb1e822f7a fix(cron): preserve provider/model on isolated-run timeout row (#95943)
* fix(cron): preserve provider/model on isolated-run timeout row

* fix(cron): carry provider/model/session into timer-built timeout rows

The reporter's blank cron_run_logs row (cron: job execution timed out
(last phase: ...)) comes from the wall-clock/cancel outcome built in
executeJobCoreWithTimeout, not the inner run catch the prior commit
patched (that catch result loses the Promise.race). Carry the
already-resolved attribution from watchdog-visible execution state into
the timer-built timeout and post-runner cancel outcomes so the persisted
row keeps provider/model/session. Pre-runner setup timeouts stay blank.

Refs #95873

* fix(cron): attribute timeout-disabled isolated-run operator-cancel rows

The timeoutSeconds:0 branch in executeJobCoreWithTimeout has no watchdog,
so it returned createOperatorCancellationOutcome() with no execution data
and never wired the execution callbacks. An operator-cancelled isolated run
with timeouts disabled still wrote a blank provider/model/session row.
Track the resolved identity locally from the same onExecutionStarted/
onExecutionPhase callbacks and carry it into the cancel outcome, matching
the timed branch. Adds a focused regression with negative control (#95873).

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 06:48:46 -07:00
Mason Huang
634a02e9e6 feat(autoreview): support cursor-agent engine (#97348)
Summary:
- The PR adds `cursor-agent` as an opt-in autoreview engine, updates the helper docs, runner dispatch, stream filtering, report parsing, and harness allowlists.
- PR surface: Docs +1, Other +99. Total +100 across 4 files.
- Reproducibility: not applicable. this is a feature PR, not a reported bug. The relevant check is source review plus maintainer validation of the external engine path.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head 807659492b.
- Required merge gates passed before the squash merge.

Prepared head SHA: 807659492b
Review: https://github.com/openclaw/openclaw/pull/97348#issuecomment-4824183439

Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Approved-by: hxy91819
2026-07-01 13:48:12 +00:00
dwc1997
f936c6b495 test(shared): add unit tests for human-readable list formatting
Squashed from PR #98605 after updating branch with current main and passing CI.
2026-07-01 06:42:54 -07:00
Masato Hoshino
5ada3acb5a feat(doctor): warn about in-flight cron jobs
Squashed from PR #98620 after updating branch with current main and passing CI.
2026-07-01 06:41:37 -07:00
Vincent Koc
be2c4c65ab fix(i18n): invalidate native artifacts on glossary changes 2026-07-01 06:16:30 -07:00
Vincent Koc
1611e04fd9 fix(ci): keep locale refresh matrices alive 2026-07-01 06:16:30 -07:00
Vincent Koc
2611ebeb2e test(ci): route shared temp-dir dependents 2026-07-01 06:16:30 -07:00
Vincent Koc
18e33d44d4 test(i18n): use shared temp directory helper 2026-07-01 06:16:30 -07:00
Vincent Koc
b881a978fb fix(ci): refresh native locales for glossary changes 2026-07-01 06:16:30 -07:00
Vincent Koc
51f5164bf4 fix(i18n): preserve native printf placeholders 2026-07-01 06:16:30 -07:00
Vincent Koc
70ef7ee2c8 fix(i18n): name Swedish in translation prompts 2026-07-01 06:16:30 -07:00
Vincent Koc
8bc40fc8de fix(i18n): validate native refresh inputs 2026-07-01 06:16:30 -07:00
Vincent Koc
a0ab8a7475 fix(i18n): allow locale placeholder reordering 2026-07-01 06:16:30 -07:00
Vincent Koc
3029006364 test(ci): guard native locale refresh retries 2026-07-01 06:16:30 -07:00
Vincent Koc
096cc881c0 test(i18n): prove native refresh creation and no-op 2026-07-01 06:16:30 -07:00
Vincent Koc
40e0b3a597 fix(i18n): guard native refresh inputs 2026-07-01 06:16:30 -07:00
Vincent Koc
4fe3d46ae7 fix(i18n): cover all native source roots 2026-07-01 06:16:30 -07:00
Vincent Koc
281e164069 fix(i18n): validate Kotlin and Swift placeholders 2026-07-01 06:16:30 -07:00