Commit Graph

35959 Commits

Author SHA1 Message Date
Vincent Koc
1bcbbbfbc1 fix(plugins): resolve registry retention lint conflicts 2026-06-24 22:12:05 +08:00
luoyanglang
5bf22d2a49 fix(plugins): reuse current metadata snapshots for tool loads 2026-06-24 22:12:04 +08:00
luoyanglang
6c37a20465 fix(plugins): keep scoped tool recovery local 2026-06-24 22:12:04 +08:00
luoyanglang
4141be5c35 fix(plugins): retain cold-loaded tool registries 2026-06-24 22:12:04 +08:00
ly-wang19
cb13be375d fix(tasks): preserve both cron-run session key shapes during maintenance (#96352)
* fix(tasks): preserve both cron-run session key shapes during maintenance

Session-registry maintenance keeps running cron jobs' session rows, but
readRunningCronJobIds built the preserve-set with job.id.toLowerCase() only.
Cron-run session keys carry two job-segment shapes: main-session runs use the
slugified segment (normalizeCronLaneSegment, e.g. "daily-report") while
default-isolated runs use the raw lowercased id ("daily report", built from
cron:${job.id} via toAgentStoreSessionKey, which lowercases but does not
slugify). The lowercase-only matcher preserved isolated runs but pruned
main-session runs of any non-slug job id (e.g. "Daily Report") as stale.

Preserve both shapes (raw lowercased id and slugified segment). This is
strictly more-preserving, so no live running cron session is dropped. Adds a
regression test seeding both a slug main-session run and a raw isolated run for
a non-slug job id, asserting both survive while a non-running job's run is still
pruned.

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

* fix(tasks): match cron session keys to target shape

* fix(tasks): preserve active cron aliases across retargeting

* fix(tasks): retain explicit cron session aliases

---------

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-24 22:10:49 +08:00
Josh Lehman
acc2a0ee72 refactor: route boot session mapping through accessor (#96225) 2026-06-24 06:54:19 -07:00
Gio Della-Libera
704fc35043 Doctor: expose session lock findings (#84366)
Merged via squash.

Prepared head SHA: 93192bb7ab
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
2026-06-24 06:53:01 -07:00
Ayaan Zaidi
f1e38f2ed6 fix(telegram): narrow rich table alignment surface 2026-06-24 06:41:38 -07:00
张贵萍0668001030
77eb0fdbaa fix(telegram): preserve rich table styling 2026-06-24 06:41:38 -07:00
snowzlmbot
f3891e1335 fix(context-engine): avoid quarantining read-only discovery factories (#96357)
* fix(context-engine): ignore read-only discovery factories

* fix(context-engine): keep discovery registrations out of runtime probes

---------

Co-authored-by: snowzlmbot <snowzlmbot@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-24 21:33:49 +08:00
Ayaan Zaidi
17066f2d7c fix(cron): preserve default toolsAllow markers safely 2026-06-24 06:26:52 -07:00
Cameron Beeley
9aea104cc8 fix(cron): stop stamping an unenforceable default toolsAllow cap on CLI runs
#91499 auto-stamps the creator's tool surface as a default toolsAllow cap
on agentTurn cron payloads whenever the creating session is tool-restricted
(a narrowing allow-policy or an explicit deny). CLI backends cannot enforce
a runtime toolsAllow — cli-runner/prepare.ts rejects any defined allow-list
— so every scheduled agentTurn that resolves to a CLI backend (e.g.
claude-cli) fails to start. This silently broke per-thread scheduled
continuations on CLI backends.

A CLI backend is not a runtime tool-policy boundary: it runs with its own
configured tool set, as the operator, on the local machine, and refuses a
runtime allow-list outright. An inherited default cap is therefore
unenforceable on a CLI backend. Decide at run time, where the backend is
known:

- Flag the default. capCronAgentTurnToolsAllow stamps toolsAllowIsDefault
  when it fills in the creator surface because the cron requested nothing
  (or a bare "*"). An explicit narrowing or empty allow-list is a real
  per-cron restriction and carries no flag.
- Drop only the default, only on CLI. The run-executor drops a flagged
  default in the CLI branch and lets the run proceed. An explicit per-cron
  restriction (no flag) is deliberately passed through, so prepare.ts still
  fails it closed and surfaces that the requested policy needs an embedded
  runtime. Embedded runs are untouched and keep the full cap enforced.
- Persist the flag. New nullable cron_jobs.payload_tools_allow_is_default
  column (additive ensureColumn migration + codec read/write) so the
  decision survives a gateway restart, plus toolsAllowIsDefault on the
  gateway-protocol agentTurn payload schema — the stamped payload is
  otherwise rejected by the contract's additionalProperties:false.
- Preserve the flag across updates. A no-toolsAllow update (reschedule,
  prompt edit) no longer carries the stored default forward as a literal
  value — that routed it through the explicit-narrowing branch, stripped the
  flag, and re-broke the job on CLI after the next restart. The default is
  re-derived (flag intact); an explicit restriction is still carried forward
  unflagged.

Net policy: on CLI only the unenforceable inherited default is relaxed;
explicit per-cron restrictions still fail closed; embedded backends are
unchanged.

Tests: run-executor drops the flagged default but propagates an explicit
restriction on CLI; cron-tool stamps/clears the flag across create and
update and preserves it across a no-toolsAllow update; store round-trips the
flag (and its absence) through SQLite.

Not covered: agentTurn crons created during the regression window carry a
flagless toolsAllow and remain fail-closed on CLI until recreated or updated
with an explicit toolsAllow.
2026-06-24 06:26:52 -07:00
Josh Lehman
c588606a9b refactor: route checkpoint mutations through accessor (#96222) 2026-06-24 06:15:09 -07:00
palomyates516-alt
ae9474b5fd fix(video): skip delivering tasks in active-task prompt guard (#96018)
Merged via squash.

Prepared head SHA: cbf32de95e
Co-authored-by: palomyates516-alt <231502129+palomyates516-alt@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-24 20:37:11 +08:00
Alexzhu
af2b0a6118 Keep agent web_search on runtime provider resolution (#88684)
Merged via squash.

Prepared head SHA: bf13efd818
Co-authored-by: alexzhu0 <178769291+alexzhu0@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-24 20:05:08 +08:00
SunnyShu
2a484a3ff1 [AI] fix(sessions): set liveModelSwitchPending when switching to default with runtime-only fields (#96318)
When a session's model comes from steering/fallback runtime fields
(entry.modelProvider/entry.model) rather than explicit override fields,
switching back to the default model via /model default would not set
liveModelSwitchPending. The isDefault branch in applyModelOverrideToSessionEntry
only sets selectionUpdated when it deletes override fields — but when no
override fields exist, selectionUpdated stays false, preventing the
liveModelSwitchPending flag from being set at the gate condition.

Fix: after the runtime alignment check, set selectionUpdated when
selection.isDefault and runtime fields are misaligned, so that
liveModelSwitchPending is properly set for the pending live switch.

Adds test coverage for this previously untested scenario.

Related to #96269

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-24 19:51:37 +08:00
miorbnli
380f2749be fix(tools-manager): require clean exit in commandExists (#96361)
Summary:
- The PR changes the agent tools manager to treat spawned-but-nonzero fd/rg probes as missing and adds regression tests for non-zero and zero spawn status.
- PR surface: Source +3, Tests +27. Total +30 across 2 files.
- Reproducibility: yes. Current main ignores non-zero `spawnSync.status`, and a live Node probe confirms a spawned child can exit non-zero while leaving `error` unset.

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

Validation:
- ClawSweeper review passed for head 377d560eff.
- Required merge gates passed before the squash merge.

Prepared head SHA: 377d560eff
Review: https://github.com/openclaw/openclaw/pull/96361#issuecomment-4788071605

Co-authored-by: liyuanbin <li.yuanbin1@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
Approved-by: takhoffman
2026-06-24 10:59:36 +00:00
Vincent Koc
bfffc77bfc feat(copilot): add BYOK provider parity 2026-06-24 18:29:56 +08:00
mushuiyu886
414c250af9 fix #95495: [Bug]: 2026.6.9 silently relocates memory store with no migration, forcing a full re-embed (1499 files) with zero upgrade-time warning (#95631)
* fix(memory): import legacy sidecar indexes into agent db

* fix(memory): move legacy sidecar import to doctor migration

* fix(memory): restore sidecar vector rows during doctor migration

* fix(memory): keep legacy sidecar when skipping import

* fix(memory): keep legacy sidecar import within extension boundary

* fix(memory-core): keep legacy sidecar migration retry-safe

* fix(memory-core): backfill sidecar FTS rows

* fix(memory-core): preserve sidecar when vector import defers

* fix(memory-core): cover custom sidecar migrations

* fix(memory-core): keep legacy config migration under doctor

* fix(memory-core): reject sidecar metadata conflicts

* fix(memory-core): keep partial legacy config sidecars

* fix(memory-core): preserve partial config retries

* fix(memory-core): keep partial config task migrations

* fix(memory-core): avoid phantom sidecar agents

* fix(memory-core): reject incomplete sidecar indexes

* fix(memory-core): keep malformed sidecars retryable

* fix(doctor): use canonical state dir for plugin migrations

* fix(memory-core): honor disabled vector sidecar migration

* fix(memory-core): treat provider-none sidecars as fts-only

* fix(memory-core): preserve setup-failed sidecars

* test(memory-core): use non-mutating sort assertions

* test(memory-core): compare sorted chunk ids

* test(memory-core): compare sorted chunk ids

* test(memory-core): stringify sorted chunk ids

* fix(qa): skip chromium bootstrap for explicit browser channels

* fix(qa): skip chromium bootstrap for explicit browser channels

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-24 17:47:44 +08:00
mmyzwl
a2725b6a24 #94162: Performance: bundle-tools loading adds 6-7s latency on every agent request (#94230)
* perf(mcp): parallelize MCP server connections in getCatalog to reduce prep latency

Every agent request incurred 6-7s of prep latency because bundle-tools
connected to configured MCP servers sequentially, one at a time. With
4-5 MCP servers at ~1.5s each (default tools/list timeout), the total
was the sum of all servers' connection times.

Fix: split getCatalog() into two phases:
1. Synchronous pre-computation of safe server names (fast, sequential)
2. Async connection + tool listing (parallelized via Promise.allSettled)

Now MCP servers connect and list tools concurrently, reducing the total
latency from the sum of all servers to roughly the slowest single server.
Each server still has its own error handling — individual failures are
gracefully demoted to diagnostics, not fatal to the catalog.

Prep stage timing change:
  Before: bundle-tools = sum(connection + listTools) for each server
  After:  bundle-tools = max(connection + listTools) across all servers

Closes #94162

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

* fix(mcp): add missing braces for eslint curly rule

Two if-statements lacked braces, failing the CI check-lint job.

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

* test(mcp): add deterministic regression test for parallel catalog loading

- Add focused timing test that proves parallel MCP catalog loading
  completes in max(server delays) not sum(server delays)
- Test creates 3 slow stdio MCP servers (200/400/600ms delays) and
  asserts wall time < sum(delays) to verify parallelism
- Would fail under the original sequential for-await loop
- Add standalone scripts/repro-94162-timing.mjs for documentation

Part of #94162

* fix(agents): bound MCP catalog fanout

* fix: harden bundle MCP catalog session lifecycle

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: mmyzwl <mmyzwl@users.noreply.github.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 16:20:23 +08:00
ly-wang19
560ecafa2d fix(model-param-b): match both adjacent <num>b tokens sharing one delimiter (#96288)
inferParamBFromIdOrName used a consuming trailing boundary `b(?:[^a-z0-9]|$)`,
so when two `<num>b` parameter tokens are separated by a single delimiter
("8b 70b", "8b-70b"), the first match ate the shared delimiter and the second
token's required leading boundary had nothing to match, silently skipping it —
returning the first (often smaller) size instead of the largest. Make the
trailing boundary a non-consuming lookahead.

Co-authored-by: ly-wang19 <ly-wang19@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 15:51:55 +08:00
Parvesh Saini
33afb1ec70 fix(commitments): keep table columns aligned when an id or scope is truncated (#95923) 2026-06-24 15:18:49 +08:00
Vincent Koc
2ab3b223ed test(gateway): stabilize suite bind defaults 2026-06-24 12:41:06 +08:00
dongdong
9e3a917d9e fix(auto-reply): align channel intro wording with chat_type (#96244)
* fix(auto-reply): use channel wording for chat_type=channel

* test(auto-reply): update channel wording fixture

* fix(auto-reply): align tool-only channel guidance

* test(auto-reply): refresh prompt snapshot

---------

Co-authored-by: Jasmine Zhang <jasminezhang@JasminedeMac-mini.local>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 12:27:04 +08:00
Sally O'Malley
487951f813 fix(compaction): route codex oauth compaction natively (#95831)
Signed-off-by: sallyom <somalley@redhat.com>
2026-06-24 00:16:01 -04:00
xdhuangyandi
89b2db77d4 fix: avoid O(N²) shallow-copy in mapSensitivePaths schema traversal (#55018)
* fix: avoid O(N²) shallow-copy in mapSensitivePaths schema traversal

* fix(config): preserve schema hint map contract

---------

Co-authored-by: 黄炎帝 <huangyandi@xiaohongshu.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 12:12:48 +08:00
Alexander Zogheb
cf86a9799c fix(agents): run heartbeat_prompt_contribution on harness prompt builds (#96233)
* fix(agents): run heartbeat_prompt_contribution on harness prompt builds

Harness runtimes (e.g. the Codex app-server) assemble the prompt through
resolveAgentHarnessBeforePromptBuildResult rather than the embedded runner's
resolvePromptBuildHookResult. The harness helper ran before_prompt_build and
before_agent_start but never invoked heartbeat_prompt_contribution, so that hook
silently no-ops on those runtimes: plugins that contribute heartbeat context via
the documented hook get nothing on heartbeat turns.

Invoke heartbeat_prompt_contribution from the harness helper too, gated on
ctx.trigger === "heartbeat", merging its prepend/append context ahead of the
before_prompt_build / before_agent_start contributions (matching the embedded
path's ordering). before_prompt_build appendContext is already honored here, so
no change is needed for boot-style append contributions.

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

* fix(agents): preserve heartbeat hook ordering

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 12:03:25 +08:00
Shakker
93bb6e6c14 test: route operator approval env setup 2026-06-24 04:45:51 +01:00
Shakker
10acda0514 fix: route approval e2e env setup 2026-06-24 04:42:48 +01:00
Shakker
bf29f73f19 test: scope chat cli home fixture 2026-06-24 04:39:03 +01:00
Shakker
3875f678a0 fix: restore chat media state env via helper 2026-06-24 04:35:05 +01:00
Shakker
c794608230 test: scope preauth env override 2026-06-24 04:30:41 +01:00
Shakker
89acdd95dc fix: restore supervisor hint env via helper 2026-06-24 04:28:13 +01:00
Yuval Dinodia
82ccee027c fix(exec): preserve turn-source routing target in approval followups for plugin channels (#96140)
* fix(exec): preserve turn-source routing target in approval followups for plugin channels

When an async exec approval is resolved and the originating session is
resumed, buildAgentFollowupArgs forwarded the turn-source to/accountId/threadId
only for built-in deliverable channels or gateway-internal channels. For an
external channel plugin whose channel is not in the in-process deliverable set,
the followup dispatched channel alone and dropped the recipient, so the resumed
agent reply routed to webchat instead of the originating channel.

Forward the turn-source routing fields whenever the resolved delivery target is
not used, matching how the channel itself is already preserved, so the gateway
can route the post-approval reply back to the originating channel.

Fixes #96103

* fix(exec): normalize followup thread routing

* fix(exec): normalize followup thread routing

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-24 11:28:03 +08:00
Shakker
c2d102b6ee test: scope post-attach sentinel env 2026-06-24 04:19:31 +01:00
sunlit-deng
2fc260aa09 fix(ports): route isPortBusy through checkPortInUse to catch IPv4-only occupants (#94949)
* fix(ports): route isPortBusy through checkPortInUse to catch IPv4-only occupants

* fix(ports): treat PortUsageStatus unknown as busy in isPortBusy

Per ClawSweeper review: checkPortInUse returns 'unknown' when every host
probe fails for a non-EADDRINUSE reason. Treating unknown as 'not busy'
could cause forceFreePortAndWait to exit before lsof/fuser inspects the
port. Conservative fix: only 'free' means not busy; everything else
(busy or unknown) triggers further inspection.

* fix(ports): reuse canonical multi-address probe

* fix(ports): reuse canonical multi-address probe

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 10:45:06 +08:00
mikasa
ce0142f04e fix #92582: Bug: doctor falsely warns local memory embeddings are not ready (#95393)
* fix(doctor): ignore skipped local embedding probe

* fix(doctor): keep skipped local model diagnostics

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-24 10:04:12 +08:00
pick-cat
20a87e17f5 fix(gateway): resolve plugin-registered gateway methods through live registry (#94154)
Merged via squash.

Prepared head SHA: c65cac4e46
Co-authored-by: Pick-cat <266665499+Pick-cat@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-24 09:49:25 +08:00
Vincent Koc
54c0048d6c perf(reply): hoist direct-send fragment index 2026-06-24 09:24:02 +08:00
Josh Lehman
96cee6cb64 refactor: route live model reads through session accessor (#96206) 2026-06-23 16:52:22 -07:00
Josh Lehman
5839ef519a refactor: migrate command session persistence to accessor (#96204)
* refactor: migrate command session writes to accessor

* refactor: narrow command session persistence params
2026-06-23 16:52:11 -07:00
Josh Lehman
ae433525f0 refactor(gateway): add alias mutation accessor (#96213)
* refactor: add gateway alias mutation accessor

* test: align gateway session entry mocks
2026-06-23 16:51:36 -07:00
Josh Lehman
95e37f8e95 refactor: guard reply session initialization (#96218)
* refactor: guard reply session initialization

* refactor: tighten reply session initialization boundary

* test: satisfy reply session accessor lint
2026-06-23 16:51:06 -07:00
Josh Lehman
6f2869c296 refactor: migrate agent session accessors (#96182)
* refactor: migrate agent session accessor writes

* refactor: move subagent orphan lookup to reconciliation

* test: align session accessor mocks
2026-06-23 16:31:43 -07:00
Josh Lehman
9512294e8f fix: bridge ACP metadata to session accessors (#96195)
* fix: bridge ACP metadata to session accessors

* fix: simplify ACP accessor key ownership

* fix: bind ACP metadata after session canonicalization
2026-06-23 16:14:53 -07:00
Josh Lehman
8a7b3c755a fix(memory-core): migrate dreaming cleanup lifecycle (#96193)
* fix(memory-core): migrate dreaming cleanup lifecycle

* fix(sessions): resolve lifecycle session files explicitly

* fix(ci): refresh dreaming lifecycle proof ratchets
2026-06-23 16:08:44 -07:00
Josh Lehman
f8ed4de460 refactor: add abort target session accessor (#96201)
* refactor: add abort target session accessor

* refactor: centralize command abort session lookup

* fix: keep abort runtime path best effort

* fix: preserve abort target identity on persistence failure

* fix: remember abort target when persistence is skipped

* fix: abort runtime before metadata persistence

* fix: preserve abort target fallback typing

* fix: avoid stale abort memory fallback

* fix: keep abort accessor ratchet narrow

* fix: type abort persistence test mock

* fix: align abort accessor ratchet test
2026-06-23 16:06:04 -07:00
Josh Lehman
b08d901dd2 fix: route gateway history through session accessor target (#96179) 2026-06-23 14:42:43 -07:00
Josh Lehman
a8f387ba19 refactor: route plugin host hook state through accessor (#96191)
* refactor: route plugin host hook state through accessor

* refactor: hide session accessor store internals
2026-06-23 14:38:40 -07:00
Josh Lehman
132d70bfb3 refactor: migrate bundled transcript target lookups (#89911) 2026-06-23 14:32:21 -07:00