Commit Graph

35645 Commits

Author SHA1 Message Date
Peter Steinberger
b721f1dbad fix: update Ollama web search endpoint 2026-04-25 22:34:43 +01:00
Cale Shapera
0bcb4c95c1 feat(tts): add Inworld speech provider (#55972)
Adds the bundled Inworld speech provider with docs, config surface, SSRF-guarded fetches, directive overrides, native voice-note/telephony output coverage, and live `.profile` verification.

Co-authored-by: cshape <cshape@users.noreply.github.com>
2026-04-25 22:33:21 +01:00
Peter Steinberger
167588cb4f test(infra): import diagnostic duplicate from source url 2026-04-25 22:19:09 +01:00
Peter Steinberger
9d22061e3e test(discord): mock message process dependencies narrowly 2026-04-25 22:19:09 +01:00
Peter Steinberger
8a731c1ef7 perf(plugin-sdk): add narrow outbound send deps entry 2026-04-25 22:19:09 +01:00
Aamir Jawaid
969f8bfd9f docs(msteams): add Teams CLI setup instructions (#71747)
* docs(msteams): add Teams CLI setup instructions

Replace manual Azure Bot setup as primary path with
@microsoft/teams.cli workflow. Manual steps collapsed
into <details> blocks for users who can't use the CLI.

* docs(msteams): fix devtunnel instructions to use persistent tunnels

Use devtunnel create + host for stable URLs across sessions
instead of throwaway tunnels that change each time.

* docs(msteams): address PR feedback

- Remove "Abandon all hope" quote (showed as net-addition in diff)
- Add preview disclaimer for @microsoft/teams.cli
- Add security note for --allow-anonymous devtunnel flag
- Clarify where to find teamsAppId from create output
- Link to official devtunnel getting started guide

* docs(msteams): fix oxfmt formatting

* docs(msteams): clarify install step references create prompt

* docs(msteams): drop --env flag, use terminal output instead

Avoids writing secrets to a file that could be accidentally committed.

* docs(msteams): remove redundant H1, match other channel docs
2026-04-25 14:18:09 -07:00
kevinlin-openai
289ed9830a Add TUI context mode selector (#71760)
Co-authored-by: kevinlin-openai <kevin@dendron.so>
Co-authored-by: Codex <noreply@openai.com>
2026-04-25 17:16:03 -04:00
Sebastien Tardif
ea4da7dfcc Add startup progress indicators (#71720)
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
2026-04-25 17:16:00 -04:00
Peter Steinberger
8f1a214a23 fix: resolve oneshot ACP identities before close 2026-04-25 22:15:52 +01:00
Shakker
cbfc0ddfd1 fix: preserve disabled plugin registry migration 2026-04-25 22:14:53 +01:00
Peter Steinberger
7d343b0b10 fix(plugins): resolve bundled channel doctor metadata from package root 2026-04-25 22:13:04 +01:00
Peter Steinberger
20223e02d9 fix(plugins): anchor runtime dependency installs 2026-04-25 22:12:26 +01:00
Peter Steinberger
0f58a6597d test: extend Windows Parallels agent turn timeout 2026-04-25 22:11:55 +01:00
Ted Li
8e83e52213 fix(memory-core): skip stale dreaming recall sources (#71695)
* fix(memory-core): skip stale dreaming recall sources

* fix(memory-core): parallelize live recall filtering
2026-04-25 17:10:38 -04:00
Yao
fbefbf05bd fix(active-memory): enforce timeoutMs as hard deadline via Promise.race (#71687)
Wrap runRecallSubagent() with Promise.race so maybeResolveActiveRecall
returns a timeout result at the configured timeoutMs even when the
embedded run has not cooperatively checked the abort signal. Late
subagent rejections are caught silently to prevent unhandled promise
errors.

Fixes #71629
2026-04-25 17:10:34 -04:00
Mara 🌿
7f5789575e fix(memory-wiki): skip bridge pruning when memory-core is not loaded (#71764)
When memory-core plugin is not registered (e.g. CLI context),
listActiveMemoryPublicArtifacts returns an empty array. The previous code
would then call pruneImportedSourceEntries with an empty activeKeys Set,
which removes ALL bridge-imported entries.

Now checks getMemoryCapabilityRegistration() instead of relying on artifact
count as a proxy, correctly distinguishing between 'plugin not loaded' and
'plugin loaded with no artifacts'.

Fixes #68373
2026-04-25 17:10:31 -04:00
Poo-Squirry
a1cb8d50ba fix: allow route bindings to override DM session scope (#71750)
Co-authored-by: 따온이네 맥북프로 <tulisy@ttaon-ine-ui-MacBookPro.local>
2026-04-25 17:08:59 -04:00
pashpashpash
bf7d156bb0 Bound native hook permission fingerprints (#71758)
* fix: bound native hook permission fingerprints

* fix: address native hook fingerprint review

* test: isolate native jiti runtime assertions
2026-04-25 17:08:56 -04:00
hcl
4a72e1b990 fix(process): skip kill-tree group kill when child wasn't detached (#71662) (#71681)
* fix(process): skip kill-tree group kill when child wasn't detached (#71662)

When the supervisor spawns a child with detached:false (service-managed
runtime under launchd/systemd), the child shares the gateway's process
group. On session abort or SIGKILL, killProcessTree was unconditionally
issuing process.kill(-pid, 'SIGTERM') — which targets the entire process
GROUP (negative pid is POSIX group-kill semantics) and therefore
SIGTERMs the gateway parent along with the child.

Reporter saw this on macOS (LaunchAgent + KeepAlive=true): aborting a
claude-cli/claude-opus-4-7 session caused the gateway to receive
SIGTERM, then auto-restart, dropping all in-flight sessions. Switching
the primary model to a non-cli provider eliminated it because the
non-cli paths don't go through this kill-tree call. Did not occur on
Linux VPS where the gateway runs detached, because there
useDetached === true and the child got its own process group.

Fix:
- killProcessTree now accepts opts.detached?: boolean. When detached:false,
  killProcessTreeUnix skips the `-pid` group-kill and goes straight to
  direct-pid SIGTERM/SIGKILL. Group-kill default (detached:true) is
  preserved so all existing callers behave exactly as before.
- supervisor/adapters/child.ts:286 now threads the spawn-time `useDetached`
  flag into killProcessTree, so the kill-tree path matches the spawn-time
  detachment decision (line 45 of the same file already computes
  useDetached = process.platform !== 'win32' && !isServiceManagedRuntime()).

Tests:
- new: detached:false skips group kill and uses direct pid SIGTERM only.
- new: default behaviour (detached:true) still uses group kill (regression
  guard so the existing test case isn't accidentally weakened).

Existing tests still pass (6/6 in kill-tree.test.ts). Lint clean.

Out of scope: other killProcessTree callers (mcp-stdio-transport,
bash-tools.process, etc.) keep the default group-kill behaviour because
those processes are typically detached from the gateway. Only the
supervisor/adapters/child.ts path threads `detached` through, since it's
the path that knows whether the child was actually spawned detached.

* fixup(process): also gate kill-tree group-kill on the no-detach spawn fallback (#71662)

Greptile review on the original PR caught a P1 gap: when
spawnWithFallback's initial detached spawn fails and it retries with the
no-detach fallback (label: "no-detach", options.detached: false), the
child runs detached:false but my variable useDetached was still true.
The kill closure then passed `detached: useDetached` = true to
killProcessTree, which still group-killed the gateway — same bug, just
on the fallback path.

Compute the actual detachment as
`useDetached && !spawned.usedFallback` after spawn returns, and pass
that through. This closes the gap: the kill path now correctly skips
group-kill in BOTH:
1. Service-managed runtime (useDetached=false from the start, original case)
2. Detached-spawn fallback to no-detach (useDetached=true at intent
   time but spawned.usedFallback=true)

Tests:
- existing 'uses process-tree kill for default SIGKILL' updated to
  assert the new {detached} option is forwarded.
- new: passes detached:false to killProcessTree when spawn fell back.
- new: passes detached:false in service-managed mode (regression guard
  for the original fix).

11/11 tests pass in child.test.ts. 6/6 in kill-tree.test.ts.
2026-04-25 17:08:53 -04:00
Evgeniy
1841dd9977 fix(subagent-announce): defer drain while parent session is busy (#71706)
When a subagent finishes while its parent main session is still running
(executing tools or awaiting model output), the announce queue would
follow the configured debounce and immediately attempt to deliver the
completion event back into the parent session via callGateway. The
gateway treats the parent as busy and the announce can either get
buffered until the next external user message or surface only as a
delayed echo, breaking the natural sessions_spawn -> sessions_yield
workflow where the parent expects the result to arrive as the next
turn.

This change adds an optional shouldDefer hook on the announce queue
state. The delivery layer wires it to the existing requester session
activity probe (resolveRequesterSessionActivity), so while the parent
session is still active the drain loop sleeps for max(250ms,
debounceMs) and re-checks instead of pushing the announce. As soon as
the parent goes idle, the queue drains normally.

- Plumbs shouldDefer through getAnnounceQueue / enqueueAnnounce.
- Skips drain step in scheduleAnnounceDrain when shouldDefer says the
  target is still busy, with a bounded re-check sleep.
- Updates maybeQueueSubagentAnnounce to pass the activity probe.
- Adds a unit test that holds drain while parent is busy and resumes
  when it goes idle.

No behavior change for callers that do not pass shouldDefer.
2026-04-25 17:08:50 -04:00
sudhindrat
ca1a6e29cb test(config): cover allowConversationAccess in plugin hooks schema validation (#71621) (#71679)
* fix(model-ref): re-add nvidia/ prefix in normalizeStaticProviderModelId (#71552)

* fix(test): use nvidia-prefixed model fixture for double-prefix guard

* test(config): cover allowConversationAccess in plugin hooks schema validation (#71621)

---------

Co-authored-by: Sudhindra Tatti <sudhi@sudhindras-mini.lan>
2026-04-25 17:08:07 -04:00
Mara 🌿
4038f734f7 fix(memory-core): add runtime cron service fallback for dreaming reconciliation (#71694)
* fix(memory-core): add runtime cron service fallback for dreaming reconciliation

When the cron service is unavailable during gateway_start (e.g., due to
a startup timing race or deferred initialization), the startupCronSource
is captured as null and never refreshed. All subsequent runtime
reconciliation attempts fail with 'cron service unavailable', even when
the cron service is fully operational.

This adds a fallback path in the runtime reconciliation that attempts to
obtain the cron service from the plugin API runtime when the startup
capture was null. This handles the case where the cron service becomes
available after the initial startup event.

Fixes #67362

* fix(memory-core): hold gateway context for runtime cron resolution

The previous attempt tried to access api.runtime.cron which doesn't exist
on the PluginRuntime type. The cron service is only accessible through
PluginHookGatewayContext.getCron().

This fix stores the gateway context from the gateway_start event and uses
it to retry cron resolution at runtime when the initial capture was null.
This handles the race condition where the cron service isn't available
during gateway_start (250ms deferred init) but is ready later.

Also refreshes the startupCron capture when the runtime retry succeeds,
so subsequent reconciliation calls resolve immediately.

Addresses review feedback on #71694
2026-04-25 17:07:45 -04:00
hcl
a97fe41a9e perf(cli): skip plugin load on agents list --json (#71739) (#71746)
Reporter measured `agents list --json` at ~7-9s on a fast host (~11s in
container) on 2026.4.23, while peer `--json` commands like
`channels list`, `cron list --all`, and `sessions ... --all-agents`
stay sub-second. Their cold-call dashboard endpoint dropped from 27s to
~2s after a local dist patch — they could even retire the 5-min cache
TTL workaround they had shipped to dodge it.

Root cause: `agents list` inherits `loadPlugins: 'always'` from the
parent `agents` policy in command-catalog, then `agentsListCommand`
calls `buildProviderStatusIndex(cfg)` unconditionally — both paths
trigger the bundled-extension import waterfall (~60+ extension index.js
modules).

`channels list` already uses `loadPlugins: 'never'` and proves the
shape is right; this PR matches that shape with the safer `text-only`
variant so human invocations are unchanged.

Two-line fix per reporter:

1. `src/cli/command-catalog.ts` — opt agents list into `text-only`,
   the same plugin-preload policy bucket that already exists. Plugin
   preload runs for human text output, skips for `--json`.

2. `src/commands/agents.commands.list.ts` — skip
   `buildProviderStatusIndex` (and the per-summary provider
   enrichment loop) when `opts.json`. Provider info is only rendered
   in human text output via `formatSummary`, so dropping it from JSON
   has no observable effect on existing callers that consume `id`,
   `name`, `model`, `bindings`, `isDefault`, `identity*`, `workspace`,
   or `agentDir`. `routes` is config-derived and continues to be set
   in both modes.

Tests:
- new assertion in command-startup-policy.test.ts: `agents list` with
  jsonOutputMode:true now resolves to `loadPlugins: false` (was
  effectively `true` via the parent `agents` 'always' policy).
- existing assertion that human (jsonOutputMode:false) still triggers
  plugin load is preserved verbatim.

6/6 tests pass. Lint clean.

Out of scope:
- `--bindings` flag opt-in for restoring providers in JSON output:
  worth adding later if any consumer needs it; reporter said dashboard
  consumers don't.
- Broader plugin-discovery cache work (#67040, #71690) which addresses
  the same family of cold-start cost.
2026-04-25 17:07:42 -04:00
sudhindrat
f92a8ae9f3 fix(model-ref): re-add nvidia/ prefix in normalizeStaticProviderModelId (#71552) (#71660)
* fix(model-ref): re-add nvidia/ prefix in normalizeStaticProviderModelId (#71552)

* fix(test): use nvidia-prefixed model fixture for double-prefix guard

---------

Co-authored-by: Sudhindra Tatti <sudhi@sudhindras-mini.lan>
2026-04-25 17:07:39 -04:00
Peter Steinberger
2febe72108 fix: isolate ACP spawned runs 2026-04-25 22:06:53 +01:00
Seungwoo hong
63fac653ed fix(talk): Talk Mode TTS improvements for CJK languages (#53553)
* feat(talk): add distinct system sounds for each Talk Mode phase

Play a short system sound on phase transitions to give the user
audible feedback:
- thinking: Tink
- speaking: Pop
- listening (after speech interrupted): Bottle
- listening (after thinking): Submarine

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

* feat(talk): add right Shift key to interrupt Talk Mode speech

Add TalkSpeechInterruptMonitor — a dedicated global key monitor that
listens for right Shift (keyCode 60) to interrupt Talk Mode speech.
Independent of Push-to-Talk, so it works even when PTT is disabled.

Stops only the current response; the next conversation cycle
continues normally via sendAndSpeak's resumeListeningIfNeeded flow.

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

* feat(talk): increase silence detection timeout for CJK locales

Korean, Japanese, and Chinese speakers need longer pauses between
phrases. When the app locale is CJK, enforce a minimum 2000ms
silence window (vs the default 1500ms) to avoid premature
transcript submission.

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

* fix(talk): remove force-unwraps and log CJK silence clamp in reloadConfig

Replace non-idiomatic force-unwraps (cfg.voiceId!, cfg.modelId!) with
safe flatMap unwrapping, and add an info log when CJK locale clamps the
silence timeout so the override is observable in diagnostics.

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

* feat(talk): add settings toggle to mute phase-transition sounds

Add a "Play phase-transition sounds" checkbox to Voice Wake settings.
When disabled, Talk Mode phase transitions (Tink/Pop/Bottle/Submarine)
are silent. Defaults to enabled to preserve existing behavior.

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

* feat(talk): add toggle for Right Option speech interrupt

Add a "Press Right Option to stop speech" checkbox to Voice Wake
settings. Also change the interrupt key from right Shift to right
Option (keyCode 61) to avoid conflicts with typing.
Defaults to enabled to preserve existing behavior.

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

* fix(talk): disable Push-to-Talk while Talk Mode is active

Talk Mode and Push-to-Talk both use the right Option key (keyCode 61).
Disable PTT when Talk Mode is enabled to prevent conflicting handlers,
and restore PTT when Talk Mode is disabled.

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

* fix(talk): show info when PTT is paused during Talk Mode

Display a footnote under the Push-to-Talk toggle when both PTT and
Talk Mode are enabled, explaining that PTT is paused while Talk Mode
is active and resumes when Talk Mode is turned off.

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

* fixup: SwiftFormat lint on TalkModeController phase sound switch

Resolves macos-swift CI lint failures introduced by Korean
comment formatting in 'feat(talk): add distinct system sounds for each Talk Mode phase'.
- Collapse consecutive spaces between sound name and comment
- Move floating comments above the listening case expression so
  they're at the correct indent level

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

---------

Co-authored-by: hongsw <hongsw@hongswui-Macmini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Fabian Williams <fabian@adotob.com>
2026-04-25 17:05:51 -04:00
Fabian Williams
d6a179bcd9 fix(macos): SwiftFormat wrapMultilineStatementBraces on 2 main files (#71763)
Pre-existing lint errors blocking the macos-swift CI check on every
PR that touches Swift code. Apply the wrapMultilineStatementBraces
rule by moving the opening brace of the multi-line if/else if to its
own line.

- apps/macos/Sources/OpenClaw/ExecAllowlistMatcher.swift:17
- apps/macos/Sources/OpenClaw/ExecApprovals.swift:621

Pure formatting change; no behavioral effect.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 17:02:13 -04:00
Vincent Koc
cdcc457d2e test(i18n): make registry test sparse-safe 2026-04-25 13:57:07 -07:00
Vincent Koc
74059aaa29 fix(secrets): honor plugin install ledger for web fetch discovery 2026-04-25 13:55:00 -07:00
Peter Steinberger
9e9e024188 docs: clarify ACP model override support 2026-04-25 21:52:36 +01:00
周辉
23a818fa2d docs: enforce background mode & direct completion in coding-agent (#53585) 2026-04-25 16:50:50 -04:00
Vincent Koc
70d1871db7 fix(secrets): honor plugin install ledger in web search risk 2026-04-25 13:50:44 -07:00
Peter Steinberger
90218364b4 test: update bundled setup-entry docker prompt 2026-04-25 21:47:24 +01:00
Peter Steinberger
9d2254be06 test(agents): make Gemini MCP smoke local 2026-04-25 21:45:57 +01:00
Peter Steinberger
17a213f080 refactor(agents): split bundle MCP CLI adapters 2026-04-25 21:45:57 +01:00
Peter Steinberger
bf672d1f2c test: harden Parallels smoke timing 2026-04-25 21:41:55 +01:00
Peter Steinberger
b49d499b45 fix: stabilize native Windows onboarding 2026-04-25 21:41:47 +01:00
Peter Steinberger
dcfd5913fd refactor(agents): share bundle MCP config merging 2026-04-25 21:36:22 +01:00
Peter Steinberger
c3a3ceefbe fix(plugins): keep mirrored runtime deps on staged root 2026-04-25 21:36:06 +01:00
pashpashpash
34fb96622e Support MCP hooks in the Codex harness (#71707)
* codex harness mcp hook parity

* tighten codex hook parity floor

* prove security-style mcp hook blocking

* bound native hook relay key handling

* clarify permission relay defers to provider

* harden native hook relay approvals

* fix(agents): bound native hook relay JSON work budget

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-04-25 21:35:47 +01:00
Peter Steinberger
e2fd3dcee9 fix(google): emit opus voice-note tts 2026-04-25 21:33:33 +01:00
Tars
d5b6667823 fix(minimax): enable portal music and video generation 2026-04-25 21:30:10 +01:00
Peter Steinberger
a8e25d9307 docs: guard maintainer-owned triage 2026-04-25 21:26:05 +01:00
Peter Steinberger
607bc53ff3 fix: import missing shell env keys 2026-04-25 21:23:45 +01:00
Peter Steinberger
6a7b76e119 fix(acp): guard sessions_spawn runtime targets 2026-04-25 21:23:24 +01:00
Vincent Koc
20c3177281 fix(plugins): satisfy setup cli fallback lint 2026-04-25 13:22:29 -07:00
Vincent Koc
07796c9fb5 fix(plugins): use registry for setup cli fallback 2026-04-25 13:22:29 -07:00
Peter Steinberger
4069c81b15 test: guard bundled runtime deps against home npm projects 2026-04-25 21:16:53 +01:00
Peter Steinberger
afabbc01b2 fix: keep bundled runtime deps in managed stage 2026-04-25 21:08:16 +01:00
Blockchain Oracle
b40df76c18 fix(cli-runtime): translate MCP transports for CLI backends
Translate OpenClaw `mcp.servers.*.transport` entries into the downstream Claude/Gemini CLI `type` field before writing bundle MCP config.

Also keeps the plugin-sdk bundled-entry fast-path fixture unambiguously CommonJS on Node 24 after runtime-deps mirroring adds a `type: "module"` boundary.

Co-authored-by: Blockchain-Oracle <ajweb3dev@gmail.com>
2026-04-25 21:08:04 +01:00