Commit Graph

17237 Commits

Author SHA1 Message Date
Peter Steinberger
a854cea4f7 fix(codex): stop supervision flag from gating the whole plugin config (#114413)
The plugin re-resolved its own enable state with supervision.enabled as
enabledByDefault, so an operator who only declared plugins.entries.codex.config
(auto-enabled by core) silently lost every codex setting, including
appServer.homeScope=user, whenever supervision was absent or off.

Use a live plugin config block as the plugin-side default, matching core's
plugin-tool-configured auto-enable and the onepassword convention. Supervision
stays gated in its own tool surface.
2026-07-27 04:34:38 -04:00
lanyoung
ae8556fed3 fix(openai): retry transient Codex device polling failures (#114094)
* fix(openai): retry transient Codex device polling failures

* fix(openai): retry transient device polling errors

Co-authored-by: lanyoung <1014080235@qq.com>

Co-authored-by: loong954 <yuan.longhui@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: loong954 <yuan.longhui@xydigit.com>
2026-07-27 04:31:48 -04:00
carlosjarenom
c93652cbe4 fix(telegram): persist update offset only after durable spool write in isolated polling (#113368)
* fix(telegram): persist update offset only after durable spool write in isolated polling

Closes #113315

In isolated polling ingress, the parent session now persists the Telegram
update offset only after the update has been durably written to the spool.
This prevents an update from being acknowledged (via the offset) before it
has been safely enqueued, which could lead to permanent data loss if the
process crashes between offset persistence and spool write.

Changes:
- Call persistUpdateId(updateId) after writeTelegramSpooledUpdate succeeds.
- Add structured logs for poll-start, update receipt, spool success/failure,
  and offset persistence success/failure.
- In isolated mode, stop passing onUpdateId to the bot so the offset is only
  persisted once, after the spool write.
- Add regression tests verifying spool-before-offset ordering and the
  failure path when spooling fails.

* fix(telegram): persist isolated polling offset only across contiguous spooled updates

Closes #113315

- Track successfully spooled update ids and advance the persisted offset only
  through a contiguous boundary. This prevents a later update_id from being
  persisted before an earlier one has finished spooling, which would make the
  earlier update unrecoverable after a restart.
- Serialize spooling while no durable offset floor exists, so the first
  successful spool becomes the persisted floor.
- Coalesce duplicate worker deliveries for the same update_id and ack both
  success and failure paths.
- Fix TypeScript cast errors in polling-session.test.ts.

* fix(telegram): serialize durable polling offsets (#113368)

---------

Co-authored-by: Carlos <carlos@example.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-07-27 17:21:03 +09:00
zengLingbiao
a8e52b49a0 fix(google): reject malformed base64 audio in Gemini TTS responses (#114041)
* fix(google): reject malformed base64 audio in Gemini TTS responses

* fix(media): validate provider audio payloads

Co-authored-by: zengLingbiao <zeng.lingbiao@xydigit.com>

* fix(xai): terminate malformed realtime audio

Co-authored-by: zengLingbiao <zeng.lingbiao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-27 04:17:35 -04:00
Peter Steinberger
669db2968f refactor(agents): retire TOOLS.md into an AGENTS.md section with a doctor migration (#113966)
* fix(agents): stop retired attestation hashes from faking a vanished workspace

* feat(agents): migrate TOOLS.md content into the AGENTS.md tools section

* refactor(agents): drop TOOLS.md from the workspace bootstrap set

* refactor(policy): read tool policy entries from AGENTS.md

* docs: describe local tool notes as an AGENTS.md section

* test(codex): drop TOOLS.md developer-instruction coverage with the removed path

* test(agents): cover the TOOLS.md doctor migration behaviors

* refactor(doctor): satisfy TOOLS.md migration lint

* test(agents): split workspace attestation survival coverage

* refactor(codex): simplify workspace context basenames

* refactor(doctor): keep TOOLS.md migration helpers module-local

* docs: regenerate docs map

* fix(doctor): keep migration claims fresh

* fix(doctor): preserve nested tool notes

* refactor(doctor): split tools migration helpers

* refactor(doctor): limit TOOLS.md migration to workspace root

* style(doctor): keep migration under line limit

* fix(doctor): recover interrupted AGENTS publish

* docs(hooks): describe root-only TOOLS.md migration accurately

* fix(doctor): preserve migrated tool guidance visibility

* test(agents): regenerate prompt snapshots after rebase

* fix(policy): block evaluation while TOOLS.md is unmigrated

* fix(doctor): check merged bootstrap budget per agent

* fix(doctor): keep budget helper internal

* refactor(doctor): keep migration budget helpers to their consumers
2026-07-27 03:56:30 -04:00
Peter Steinberger
08b1ff73e2 refactor(channels): fix account resolution and setup isolation (#114395)
* refactor(channels): fix account resolution and setup isolation

* fix(channels): keep account resolvers safely destructurable
2026-07-27 03:49:37 -04:00
Peter Steinberger
3c67fcc45d fix(release): stabilize beta validation and completion (#114396)
* test(release): fix rebased validation gates

* test(migrate-hermes): use canonical auth store fixture

* test(secrets): reset runtime state before migration isolation

* test(secrets): reload singleton graph for migration isolation

* test(secrets): isolate auth migration state

* fix(release): return completed validation run

* docs: refresh docs map after forward-port
2026-07-27 03:42:00 -04:00
Peter Steinberger
eec2c0cc26 refactor(providers): unify lifecycle-safe manifest registration (#114381)
* refactor(providers): canonicalize manifest-driven registration

* fix(zai): eliminate type-only SDK import side effects
2026-07-27 03:20:02 -04:00
Peter Steinberger
65cce37480 fix(codex): keep user-home app-servers on native Codex auth (#114397)
A prepared OpenClaw auth handoff was still resolved for connections that
target the operator's native Codex home, so every turn failed with
"Prepared Codex auth requires an isolated app-server home." once a stored
OpenAI profile produced a prepared model route. User-home mode now keeps
its native account for both subscription and Platform routes, matching the
documented contract; the shared-client guard stays as the backstop.
2026-07-27 03:19:06 -04:00
Peter Steinberger
3e4c57dbeb fix(onepassword): resolve secret refs under Bun by dropping execa buffer encoding (#114346) 2026-07-27 03:15:17 -04:00
Pavan Kumar Gondhi
33f44caa5d fix: restrict QQBot quoted context [AI] (#114136)
* fix: restrict qqbot quoted context

* fix: narrow qqbot bot quote exemption

* test: use valid qqbot ingress reasons

* fix: honor narrowed qqbot open dm quotes

* fix: honor narrowed qqbot open group quotes

* test: use valid qqbot blocked ingress decisions

* fix: honor qqbot quote visibility mode

* docs: mention qqbot context visibility

* fix: validate qqbot context visibility config

* fix: hide denied qqbot quote sender

* test: avoid unbound qqbot access mock

* test: allow auth migration isolation to finish

* Revert "test: allow auth migration isolation to finish"

This reverts commit f2b9a4f5e9.
2026-07-27 12:23:21 +05:30
Peter Steinberger
7b71d5608e perf(gateway): reuse session catalog entry snapshots per request (#114358)
* perf(gateway): reuse session catalog entry snapshots

* chore(gateway): satisfy knip and typed-test lanes for catalog snapshot
2026-07-27 02:14:11 -04:00
Peter Lee
0406e66369 fix(ui): keep stable chat rows in insertion order and only sort live tool/stream items by timestamp (#113266)
* fix(ui): keep stable chat rows in insertion order and only sort live tool/stream items by timestamp

* fix(ui): keep live rows within current turn

* fix(ui): keep current work above queued turns

* fix(ui): keep streamed replies above queued turns

* fix(ui): preserve reconnecting run order

* fix(ui): preserve causal terminal ordering

* fix(ui): bound replay rows to owning turns

* fix(ui): keep question summaries in owning turns

* fix(ui): scope question run ownership to session

* fix(ui): restore reconnecting chat run identity

* fix(ui): remove unused chatItemTimestamp import in chat-thread-build.ts

* fix(ui): correlate question summaries with agent runs

Co-authored-by: Peter Lee <li.xialong@xydigit.com>

* chore(i18n): refresh native source baseline

Co-authored-by: Peter Lee <li.xialong@xydigit.com>

* fix(ui): remove unused chatItemTimestamp export and split tool-stream test file

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-27 02:08:22 -04:00
Dallin Romney
9310586b09 fix(qa-lab): unify runner control plane (#112838) 2026-07-27 14:05:14 +08:00
Peter Steinberger
0642072b70 test(providers): consolidate catalog and realtime contract cases (#114352) 2026-07-27 01:55:20 -04:00
Peter Steinberger
8e4b6623e5 test(providers): consolidate streaming and model contract cases (#114336) 2026-07-27 01:36:32 -04:00
Peter Steinberger
dc8fdb1756 refactor(providers): derive simple providers from manifests (#114331) 2026-07-27 01:29:53 -04:00
Peter Steinberger
1c42998f0d refactor(retry): consolidate abort-safe ClawHub and memory retries (#114300)
* refactor(retry): reuse canonical abort-safe retry policies

* fix(retry): keep retry-after parsing source-safe
2026-07-27 01:25:40 -04:00
Peter Steinberger
cba38b74a3 improve(slack): consolidate transport regression coverage (#114329) 2026-07-27 01:24:49 -04:00
Momo
16d2b7e467 fix(memory-lancedb): make table initialization atomic (#105896)
* fix(memory-lancedb): make table init atomic

# Conflicts:
#	extensions/memory-lancedb/index.ts

* fix(memory-lancedb): stabilize concurrent table init
2026-07-27 12:57:24 +08:00
Peter Steinberger
7cce91cda9 refactor(channels): unify account and setup adapters (#114290) 2026-07-27 00:55:46 -04:00
Peter Steinberger
60aac74672 fix(openai): harden live and packaged onboarding (#114288) 2026-07-27 00:50:49 -04:00
dandriscoll
71eb9a3ec9 fix: Telegram forum topics answered twice (duplicate conversation per topic) (#113063)
* fix: Telegram forum topics answered twice (duplicate conversation per topic)

* fix(telegram): repair General topic conversation identity

Co-authored-by: Dan Driscoll <thedandriscoll.org@gmail.com>

* fix: keep doctor repair detail internal

---------

Co-authored-by: Dan Driscoll <thedandriscoll.org@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-27 00:42:00 -04:00
Dallin Romney
b699a93c87 fix(qa): stop live config waits from timing out (#114112)
* fix(ci): start QA script scenarios in parallel

* fix(qa): stop false live config waits
2026-07-27 12:18:20 +08:00
joshavant
44378dd24a fix(channels): harden record session override 2026-07-26 23:15:06 -05:00
joshavant
1b16d12b58 fix(discord): clear cancelled interaction defers 2026-07-26 23:15:06 -05:00
joshavant
d8de71258a refactor(channels): route bundled command replies 2026-07-26 23:15:06 -05:00
Eden
0c35fd578b fix(line): keep replies deliverable when action data or button URLs exceed LINE's size caps (#113081)
* fix(line): cap flex postback data and action URIs at LINE's size limits

* fix(line): preserve encoded action boundaries

* fix(line): surface unavailable oversized actions

* fix(line): centralize oversized callback fallback

* test(line): pin UTF-16 action limits

* fix(line): fit fallback labels in image carousels

* fix(line): normalize raw actions at builder boundaries

* fix(line): normalize remaining flex actions

* fix(line): enforce action limits at send boundary

* fix(line): preserve message action identity

* fix(line): surface unavailable video links

* fix(line): render non-button action warnings

* fix(line): count action limits by code point

* fix(line): normalize imagemap actions

* fix(line): normalize imagemap video links

* fix(line): bound imagemap video labels

* fix(line): satisfy code-point lint guard

* fix(line): finalize imagemap action limits

Co-authored-by: 許元豪 <146086744+edenfunf@users.noreply.github.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-26 23:46:02 -04:00
Peter Steinberger
04bb2b7ee9 fix(openai): make onboarding models account-aware (#114258) 2026-07-26 23:33:57 -04:00
Peter Steinberger
e717d24c2e refactor(meetings): close manual action state (#114247) 2026-07-26 23:25:19 -04:00
Vito Cappello
5ae8a4f4f9 fix: preserve Claude cache during stalled CLI recovery (#113866)
* Preserve Claude cache during stalled CLI recovery

* fix(agents): harden Claude stall recovery

* fix(agents): reject partial Claude recovery output

* fix(agents): rewind Claude recovery to a safe checkpoint

* fix(agents): preserve checkpointed fork retries

* fix(agents): cold-reseed downgraded Claude forks

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-26 23:11:39 -04:00
Peter Steinberger
37182b9050 refactor(channels): declare thread addressing as a channel trait (#114245)
* refactor(channels): declare thread addressing as a channel trait

* fix(tasks): require declared thread capability for direct parent-review delivery

* docs(tasks): record the no-target-parsing tradeoff at the delivery gate
2026-07-26 23:05:13 -04:00
Dallin Romney
c1c231ced9 fix(qa): reject runtime tool intent without result evidence (#113502)
* fix(qa): require runtime tool result evidence

* fix(qa): preserve meaningful tool coverage gates

* refactor(qa): colocate runtime parity projection

* fix(qa): keep passing tool totals evidence-backed
2026-07-27 11:00:59 +08:00
Peter Steinberger
83307f6bc7 refactor(irc): delegate outbound sends to message adapter (#114235) 2026-07-26 22:10:51 -04:00
Peter Steinberger
7594e09100 refactor(meetings): centralize talk-back readiness (#114229) 2026-07-26 22:03:12 -04:00
Peter Steinberger
5d74ba56f8 refactor(volcengine): reuse model compat patcher (#114232) 2026-07-26 21:58:27 -04:00
Peter Steinberger
5804d023ec refactor(qqbot): inject live config accessor (#114227) 2026-07-26 21:45:21 -04:00
JesusSerrano-Seimako
0ac926b8fb fix(telegram): scope dispatch dedupe by bot identity (#113667)
* fix(telegram): scope dispatch dedupe by bot identity

* refactor(telegram): require bot identity for dispatch dedupe

* docs(telegram): explain dedupe key cutover

---------

Co-authored-by: JesusSerrano-Seimako <269908146+JesusSerrano-Seimako@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-07-27 07:04:48 +05:30
Peter Steinberger
f88d618589 refactor(providers): share admin usage aggregation (#114221) 2026-07-26 21:28:53 -04:00
Jesse Merhi
d7627d6f4c refactor(prompt): use plain inbound context labels and drop system-tag sanitizer (#112000)
* refactor(prompt): plain inbound context labels with a provenance marker

Replaces trust-worded inbound context labels ("(untrusted metadata)",
"(untrusted, for context)") with plain labels plus a fixed provenance
marker suffix appended to every OpenClaw-injected context header.

Detection keys on the marker, not label text, so strippers stay correct
across UI, TUI, replay, /trace segmentation, memory recall, and the Swift
chat preprocessor. Drops sanitizeInboundSystemTags in favor of the marker
boundary plus trusted system-prompt narration.

Renames the untrusted-named plugin SDK context identifiers to
channel-provenance names, keeping deprecated aliases registered for
removal after 2026-09-08.

Adds `openclaw doctor --fix` migrations that rewrite legacy inbound
labels in stored SQLite transcripts and purge legacy envelope-
contaminated LanceDB recall rows.

* fix(ci): resolve gate failures for plain inbound context labels

- doctor sqlite readers: open read-only connections via openNodeSqliteDatabase
  so the Kysely connection-boundary guardrail holds; unexport the now-internal
  transcript snapshot type (Knip unused-export gate).
- compat registry: split the record table into registry-records.ts and
  plugin-sdk-subpath-records.ts. The new compat record pushed registry.ts past
  the 700-line oxlint cap; suppressions are disallowed, so follow the existing
  sibling record-module pattern. Public exports and PluginCompatCode literals
  unchanged.
- acp-runtime test: assert current finalization behavior (newline normalization
  only). The bracket de-fang and System: rewrite it expected were removed with
  sanitizeInboundSystemTags; forged system lines are neutralized at the
  system-event queue, the single chokepoint feeding the System:-per-line render.
- regenerate docs_map and the plugin SDK API baseline manifest.

* fix(prompt): harden inbound context label migration and drop in-band sanitizer

Review follow-ups on the plain-label + provenance-marker change:

- Remove src/security/system-tags.ts. Rewriting inbound text to neutralize
  look-alike `System:`/`[System]` markers corrupted legitimate user text and is
  not a real injection boundary; role separation plus external-content wrapping
  is. Explicit product decision, recorded at the system-event queue.
- Narrow the LanceDB legacy-row purge so it cannot delete benign memories. It
  now requires a complete known legacy sentinel line, a legacy label followed by
  a fenced JSON body, or the complete legacy external-content header. The prior
  predicates matched ordinary prose such as `Notes (untrusted metadata):`, and
  deletion is irreversible.
- Make explicit-empty canonical ChannelStructuredContext win over the deprecated
  alias via a present/absent result instead of collapsing `[]` to undefined.
- Keep `\r?` in the active-memory doctor rule. It is the only rule spanning the
  header's line break, migrated assistant rows skip newline normalization, and
  without it the marked-header replace wins and the body strips to empty. Added
  a CRLF regression test.
- Fix stale comments that described removed behavior, and cover the Swift
  prose-block strip path.

Claude-Session: https://claude.ai/code/session_01WNzsPddQmxy9Y7jKD4wAxH
2026-07-27 11:27:53 +10:00
Jason (Json)
0f6a693acd fix(models): shape unreleased Claude ids with the newest known contract (#114205)
Request shaping is selected by version predicates in llm-core, so a Claude id
from a generation newer than anything the plugin encodes fell through to pre-4.6
shaping: manual budget_tokens thinking plus caller sampling parameters, both of
which current models reject.

Resolve such an id through the plugin's existing forward-compat path and stamp
params.canonicalModelId, the same seam Bedrock and Mantle use to map a
provider-native id onto a canonical Claude contract. Shared contracts are
untouched, so Claude served through third-party providers keeps its own
shaping.
2026-07-26 18:46:34 -06:00
keshavbotagent
46f4018ff9 fix(codex): recover in-place session resets (#114056)
* fix(codex): recover in-place session resets

* fix(codex): preserve retired generation fences

---------

Co-authored-by: Josh Lehman <josh@martian.engineering>
2026-07-26 16:49:57 -07:00
Patrick Erichsen
898e10c0f4 docs(buzz): shorten plugin readme (#114156) 2026-07-26 14:21:36 -05:00
Jason (Json)
4bb8df63ca fix(models): authenticate Anthropic discovery with OAuth tokens (#113906)
* fix(models): authenticate Anthropic discovery with OAuth tokens

Live model discovery sent every credential as x-api-key. Claude subscription
credentials are OAuth access tokens, which Anthropic rejects in that header, so
discovery 401d and silently fell back to the shipped catalog.

Select the auth header from the detected credential shape: API keys keep
x-api-key, OAuth tokens use Authorization: Bearer. The two are mutually
exclusive because Anthropic rejects requests carrying both.

* fix(models): keep shipped Anthropic models when discovery succeeds

Live discovery replaces the seed catalog with the /v1/models response. Anthropic
does not publish every model it serves, so a shipped entry with no live row was
dropped from the provider listing once discovery started working.

Re-add manifest models the live response omitted; discovered rows still win on
shared ids.
2026-07-26 12:19:57 -06:00
Peter Steinberger
cca5b14785 feat(ui): path-based session and dashboard URLs (#113883)
* feat(ui): path-based session and dashboard URLs

* docs(ui): document control UI URLs

* fix(ui): finalize session path routing

* feat(ui): anchor session URLs on stable keys

* docs(ui): clarify stable session URL identity

* fix(ui): resolve session prefixes with full prefix and pagination

Query sessions.list with the full supplied prefix instead of an eight-char
truncation, and paginate up to a bounded page count so longer disambiguation
links resolve instead of being reported ambiguous. Zero strict-prefix matches
now fall through to literal-key resolution rather than rendering an empty
ambiguity view.

Also document the ~dot/~dotdot segment escape: peer ids reach session keys
trimmed and lowercased only (src/routing/session-key.ts), so a literal '.' or
'..' segment is reachable and browsers would normalize it away.

* fix(ui): synchronize committed session routes

* test(ui): split native shell host coverage

* fix(ui): thread configured mainKey through session URL builders

Reserved-set disambiguation needs the operator-configured mainKey at runtime, so
thread it from agentsList through every session path builder and the ClickClack
control URL. Unambiguous non-hex single-segment rests now resolve literally while
short-id-shaped rests still fail closed, which restores ClickClack channel
compatibility detection and control-link reconciliation.

Also bound prefix-resolution retries, preserve catalog thread identity, and keep
draft state on ambiguous candidate links.

* fix(ui): repair session URL CI integration

* perf(ui): lazy-load session route resolution

* perf(ui): isolate session prefix resolution

* perf(ui): defer session path parsing

* perf(ui): defer session navigation startup

* fix(ui): preserve first-run and literal session navigation

* fix(ui): satisfy session routing type and export gates

* fix(clickclack): preserve unscoped control link agent

* style(ui): satisfy chat page line limit

* refactor(ui): move chat page helpers to owning modules

* fix(ui): preserve destination session route identity

* fix(ui): preserve agent identity in session routes

* fix(ui): escape dots in literal session path segments

encodeURIComponent leaves periods intact, so a literal key segment like
channel:release.js produced /chat/main/channel/release.js. In-app navigation is
intercepted by the SPA, but a refresh, an external link, or a ClickClack link
would be served as a static asset request and never reach the app.

pathForWorkboardBoard already escapes dots for this reason; mirror it in both the
session URL contract and the ClickClack encoder, route the agent id through the
same segment encoder, and pin the case in both shared vector tables.

* fix(ui): stop bootstrap after teardown race

* refactor(ui): centralize session navigation targets

* fix(ui): consume bootstrap teardown abort

* fix(ui): canonicalize configured main session routes

* fix(ui): preserve distinct session references

* fix(ui): redirect released session query links

* fix(ui): make bootstrap teardown abort-safe
2026-07-26 12:46:04 -04:00
Peter Steinberger
bba7e30fcc fix(browser): preserve nested timeouts and cancellation across node actions (#114131) 2026-07-26 12:04:52 -04:00
Shakker
8f524a23b2 fix: satisfy Buzz CI boundaries (#113419) 2026-07-26 14:09:23 +01:00
Shakker
04cafe601b fix: make Buzz rooms usable by default (#113419) 2026-07-26 14:09:23 +01:00
Shakker
fa2ca9dfbb fix: clear recovered Buzz status errors 2026-07-26 14:09:23 +01:00
Shakker
ffb00ca624 fix: register Buzz agent identities 2026-07-26 14:09:23 +01:00