Commit Graph

16278 Commits

Author SHA1 Message Date
Alex Filatov
f181b7dbe6 Add OpenAI OAuth TLS preflight and doctor prerequisite check 2026-03-02 13:24:49 -08:00
scoootscooob
0f1388fa15 fix(gateway): hot-reload channelHealthCheckMinutes without full restart
The health monitor was created once at startup and never touched by
applyHotReload(), so changing channelHealthCheckMinutes only took
effect after a full gateway restart.

Wire up a "restart-health-monitor" reload action so hot-reload can
stop the old monitor and (re)create one with the updated interval —
or disable it entirely when set to 0.

Closes #32105

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:23:20 +00:00
Peter Steinberger
b782ecb7eb refactor: harden plugin install flow and main DM route pinning 2026-03-02 21:22:38 +00:00
Peter Steinberger
af637deed1 fix: propagate whatsapp inbound fromMe context (#32167) (thanks @scoootscooob) 2026-03-02 21:20:21 +00:00
scoootscooob
73e6dc361e fix(whatsapp): propagate fromMe through inbound message pipeline
The `fromMe` flag from Baileys' WAMessage.key was only used for
access-control filtering and then discarded.  This meant agents
could not distinguish owner-sent messages from contact messages
in DM conversations (everything appeared as from the contact).

Add `fromMe` to `WebInboundMessage`, store it during message
construction, and thread it through `buildInboundLine` →
`formatInboundEnvelope` so DM transcripts prefix owner messages
with `(self):`.

Closes #32061

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:20:21 +00:00
Peter Steinberger
866bd91c65 refactor: harden msteams lifecycle and attachment flows 2026-03-02 21:19:23 +00:00
Peter Steinberger
d98a61a977 fix(config): move sensitive-schema hint warnings to debug 2026-03-02 21:13:58 +00:00
Peter Steinberger
d01e04bcec test(perf): reduce heavy fixture and guardrail overhead 2026-03-02 21:07:52 +00:00
Peter Steinberger
5a32a66aa8 perf(core): speed up routing, pairing, slack, and security scans 2026-03-02 21:07:52 +00:00
Peter Steinberger
3a08e69a05 refactor: unify queueing and normalize telegram slack flows 2026-03-02 20:55:15 +00:00
Peter Steinberger
320920d523 fix: harden bundled plugin install fallback semantics (#32096) (thanks @scoootscooob) 2026-03-02 20:49:50 +00:00
Peter Steinberger
ad12d1fbce fix(plugins): prefer bundled plugin ids over bare npm specs 2026-03-02 20:49:50 +00:00
scoootscooob
bfb6c6290f fix: distinguish warning message for non-OpenClaw vs missing npm package
Address Greptile review: show "not a valid OpenClaw plugin" when the
npm package was found but lacks openclaw.extensions, instead of the
misleading "npm package unavailable" message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:49:50 +00:00
scoootscooob
da8a17d8de fix(plugins): fall back to bundled plugin when npm spec resolves to non-OpenClaw package (#32019)
When `openclaw plugins install diffs` downloads the unrelated npm
package `diffs@0.1.1` (which lacks `openclaw.extensions`), the install
fails without trying the bundled `@openclaw/diffs` plugin.

Two fixes:
1. Broaden the bundled-fallback trigger to also fire on
   "missing openclaw.extensions" errors (not just npm 404s)
2. Match bundled plugins by pluginId in addition to npmSpec so
   unscoped names like "diffs" resolve to `@openclaw/diffs`

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:49:50 +00:00
Peter Steinberger
089a8785b9 fix: harden msteams revoked-context fallback delivery (#27224) (thanks @openperf) 2026-03-02 20:49:03 +00:00
root
e0b91067e3 fix(msteams): add proactive fallback for revoked turn context
Fixes #27189

When an inbound message is debounced, the Bot Framework turn context is
revoked before the debouncer flushes and the reply is dispatched. Any
attempt to use the revoked context proxy throws a TypeError, causing the
reply to fail silently.

This commit fixes the issue by adding a fallback to proactive messaging
when the turn context is revoked:

- `isRevokedProxyError()`: New error utility to reliably detect when a
  proxy has been revoked.

- `reply-dispatcher.ts`: `sendTypingIndicator` now catches revoked proxy
  errors and falls back to sending the typing indicator via
  `adapter.continueConversation`.

- `messenger.ts`: `sendMSTeamsMessages` now catches revoked proxy errors
  when `replyStyle` is `thread` and falls back to proactive messaging.

This ensures that replies are delivered reliably even when the inbound
message was debounced, resolving the core issue where the bot appeared
to ignore messages.
2026-03-02 20:49:03 +00:00
Peter Steinberger
d2bb04b436 fix: document msteams auth redirect scoping hardening (#25045) (thanks @bmendonca3) 2026-03-02 20:45:09 +00:00
bmendonca3
4a414c5e53 fix(msteams): scope auth across media redirects 2026-03-02 20:45:09 +00:00
bmendonca3
da22a9113c test(msteams): cover auth stripping on graph redirect hops 2026-03-02 20:45:09 +00:00
bmendonca3
8937c10f1f fix(msteams): scope graph auth redirects 2026-03-02 20:45:09 +00:00
Peter Steinberger
259f6543b4 fix: harden config backup permissions and cleanup (#31718) (thanks @YUJIE2002) 2026-03-02 20:40:15 +00:00
YUJIE2002
3c0ec76e8e fix(config): harden backup file permissions and clean orphan .bak files
Addresses #31699 — config .bak files persist with sensitive data.

Changes:
- Explicitly chmod 0o600 on all .bak files after creation, instead of
  relying on copyFile to preserve source permissions (not guaranteed on
  all platforms, e.g. Windows, NFS mounts).
- Clean up orphan .bak files that fall outside the managed 5-deep
  rotation ring (e.g. PID-stamped leftovers from interrupted writes,
  manual backups like .bak.before-marketing).
- Add tests for permission hardening and orphan cleanup.

The backup ring itself is preserved — it's a valuable recovery mechanism.
This PR hardens the security surface by ensuring backup files are
always owner-only and stale copies don't accumulate indefinitely.
2026-03-02 20:40:15 +00:00
Peter Steinberger
d80144f572 fix: keep long Telegram model callbacks selectable (#31857) (thanks @bmendonca3) 2026-03-02 20:38:43 +00:00
bmendonca3
54eb13893f Telegram: support compact model callback fallback 2026-03-02 20:38:43 +00:00
bmendonca3
c582a54554 fix(msteams): preserve guarded dispatcher redirects 2026-03-02 20:37:47 +00:00
bmendonca3
cceecc8bd4 msteams: enforce guarded redirect ownership in safeFetch 2026-03-02 20:37:47 +00:00
Jason Separovic
00347bda75 fix(tools): strip xAI-unsupported JSON Schema keywords from tool definitions
xAI rejects minLength, maxLength, minItems, maxItems, minContains, and
maxContains in tool schemas with a 502 error instead of ignoring them.
This causes all requests to fail when any tool definition includes these
validation-constraint keywords (e.g. sessions_spawn uses maxLength and
maxItems on its attachment fields).

Add stripXaiUnsupportedKeywords() in schema/clean-for-xai.ts, mirroring
the existing cleanSchemaForGemini() pattern. Apply it in normalizeToolParameters()
when the provider is xai directly, or openrouter with an x-ai/* model id.

Fixes tool calls for x-ai/grok-* models both direct and via OpenRouter.
2026-03-02 20:37:07 +00:00
Kay-051
da05395c2a fix(telegram): preserve original filename from Telegram document/audio/video uploads
The downloadAndSaveTelegramFile inner function only used the server-side
file path (e.g. "documents/file_42.pdf") or the Content-Disposition
header (which Telegram doesn't send) to derive the saved filename.
The original filename provided by Telegram via msg.document.file_name,
msg.audio.file_name, msg.video.file_name, and msg.animation.file_name
was never passed through, causing all inbound files to lose their
user-provided names.

Now downloadAndSaveTelegramFile accepts an optional telegramFileName
parameter that takes priority over the fetched/server-side name.
The resolveMedia call site extracts the original name from the message
and passes it through.

Closes #31768

Made-with: Cursor
2026-03-02 20:36:39 +00:00
Altay
e45d26b9ed chore(gitignore): add .claude folder to gitignore (#32141) 2026-03-02 12:35:56 -08:00
bmendonca3
16e7fc2563 fix(models): infer codex weekly usage labels from reset cadence 2026-03-02 20:35:45 +00:00
SidQin-cyber
479095bcfb fix(discord): use per-channel message queues to restore parallel agent dispatch
Replace the single per-account messageQueue Promise chain in
DiscordMessageListener with per-channel queues. This restores parallel
processing for channel-bound agents that regressed in 2026.3.1.

Messages within the same channel remain serialized to preserve ordering,
while messages to different channels now proceed independently. Completed
queue entries are cleaned up to prevent memory accumulation.

Closes #31530
2026-03-02 20:34:41 +00:00
SidQin-cyber
5b63417fec fix(slack): apply mrkdwn conversion in streaming and preview paths
The native streaming path (chatStream) and preview final edit path
(chat.update) send raw Markdown text without converting to Slack
mrkdwn format. This causes **bold** to appear as literal asterisks
instead of rendered bold text.

Apply markdownToSlackMrkdwn() in streaming.ts (start/append/stop) and
in dispatch.ts (preview final edit via chat.update) to match the
non-streaming delivery path behavior.

Closes #31892
2026-03-02 20:34:41 +00:00
bmendonca3
6945ba189d msteams: harden webhook ingress timeouts 2026-03-02 20:34:05 +00:00
webdevtodayjason
ab0b2c21f3 WhatsApp: guard main DM last-route to single owner 2026-03-02 20:33:59 +00:00
Mitch McAlister
f534ea9906 fix: prevent reasoning text leak through handleMessageEnd fallback
When enforceFinalTag is active (Google providers), stripBlockTags
correctly returns empty for text without <final> tags. However, the
handleMessageEnd fallback recovered raw text, bypassing this protection
and leaking internal reasoning (e.g. "**Applying single-bot mention
rule**NO_REPLY") to Discord.

Guard the fallback with enforceFinalTag check: if the provider is
supposed to use <final> tags and none were seen, the text is treated
as leaked reasoning and suppressed.

Also harden stripSilentToken regex to allow bold markdown (**) as
separator before NO_REPLY, matching the pattern Gemini Flash Lite
produces.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:32:01 +00:00
chilu18
15677133c1 test(msteams): remove tuple-unsafe spread in lifecycle mocks 2026-03-02 20:31:26 +00:00
chilu18
c9d0e345cb fix(msteams): keep monitor alive until shutdown 2026-03-02 20:31:26 +00:00
liuxiaopai-ai
bf0653846e Gateway: suppress NO_REPLY lead-fragment chat leaks 2026-03-02 20:27:49 +00:00
Peter Steinberger
3de7768b11 perf(routing): cache normalized agent-id lookups 2026-03-02 20:19:10 +00:00
Peter Steinberger
2937fe0351 perf(config): skip redundant schema and session-store work 2026-03-02 20:19:10 +00:00
Peter Steinberger
fb5d8a9cd1 perf(slack): memoize allow-from and mention paths 2026-03-02 20:19:10 +00:00
Peter Steinberger
2f352306fe perf(security): cache scanner directory walks 2026-03-02 20:19:10 +00:00
Peter Steinberger
f7765bc151 perf(cron): cache schedule evaluators and stagger offsets 2026-03-02 20:19:10 +00:00
Jean-Marc
b52561bfa3 fix(synology-chat): prevent restart loop in startAccount (#23074)
* fix(synology-chat): prevent restart loop in startAccount

startAccount must return a Promise that stays pending while the channel
is running. The gateway wraps the return value in Promise.resolve(), and
when it resolves, the gateway thinks the channel crashed and auto-restarts
with exponential backoff (5s → 10s → 20s..., up to 10 attempts).

Replace the synchronous { stop } return with a Promise<void> that resolves
only when ctx.abortSignal fires, keeping the channel alive until shutdown.

Tested on Synology DS923+ with DSM 7.2 — single startup, no restart loop.

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

* fix(synology-chat): add type guards for startAccount return value

startAccount returns `void | { stop: () => void }` — TypeScript requires
a type guard before accessing .stop on the union type. Added proper checks
in both integration and unit tests.

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

* fix(synology-chat): use Readable stream in integration test for Windows compat

Replace EventEmitter + process.nextTick with Readable stream for
request body simulation. The process.nextTick approach caused the test
to hang on Windows CI (120s timeout) because events were not reliably
delivered to readBody() listeners.

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

* fix: stabilize synology gateway account lifecycle (#23074) (thanks @druide67)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-03-02 20:06:16 +00:00
Peter Steinberger
4b50018406 fix: restore helper imports and plugin hook test exports 2026-03-02 19:57:33 +00:00
Peter Steinberger
7003615972 fix: resolve rebase conflict markers 2026-03-02 19:57:33 +00:00
Peter Steinberger
eb816e0551 refactor: dedupe extension and ui helpers 2026-03-02 19:57:33 +00:00
Peter Steinberger
b1c30f0ba9 refactor: dedupe cli config cron and install flows 2026-03-02 19:57:33 +00:00
Peter Steinberger
9d30159fcd refactor: dedupe channel and gateway surfaces 2026-03-02 19:57:33 +00:00
Peter Steinberger
9617ac9dd5 refactor: dedupe agent and reply runtimes 2026-03-02 19:57:33 +00:00