Commit Graph

38 Commits

Author SHA1 Message Date
Peter Steinberger
ee2b4e5acc fix(sms): prevent silent loss of acknowledged Twilio messages (#109866)
* fix(sms): adopt durable ingress drain with ack gated on MessageSid enqueue

Twilio inbound webhooks acked 200 then dispatched detached behind a 10-minute
in-memory replay guard; Twilio does not reliably retry inbound messages, so a
crash between ack and dispatch silently lost the SMS. The raw Twilio form now
enqueues durably (event_id = MessageSid, lane per sender) before the TwiML
200; dispatch, retry, dead-letter, and tombstones run through the core drain
with a startup + interval pump for restart recovery. Payload/account
validation moved to parse-at-dispatch and dead-letters as non-retryable. The
replay guard and its saturation 429 path are deleted; 24h/20k tombstones
strictly cover the old 10min/10k window.

Autoreview P1 (ambiguous non-adopted settlement) rejected with evidence:
bindIngressLifecycleToReplyOptions threads onAdopted/onDeferred/onAbandoned
into reply admission, so deferral and abandonment settle via core lifecycle
callbacks; normal non-adopted return = terminal local handling, matching the
Telegram reference mapping (skipped -> completed). Part of #109657 wave 1.

* fix(sms): keep ingress payload type internal

* fix(sms): preserve Twilio message SID aliases

* fix(sms): preserve ingress ordering and timestamps

* test(sms): satisfy type and lint gates
2026-07-17 11:11:13 +01:00
Peter Steinberger
0e792b6de3 refactor(channels): centralize inbound orchestration and remove internal compat (#109716)
* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
2026-07-17 00:56:46 -07:00
RileyJJY
786ad1dbf8 fix(sms): ignore blank Twilio env account fallbacks (#109149)
* fix(sms): ignore blank Twilio env account fallbacks

* refactor(sms): reuse configured account value predicate

Co-authored-by: RileyJJY <0668000974@xydigit.com>

* test(sms): keep blank account fixture minimal

Co-authored-by: RileyJJY <0668000974@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 14:19:21 -07:00
DaigoSoup
fa08ab28ca fix(telegram): preserve word boundaries in proactive sends (#108801)
* fix(telegram): preserve proactive message word boundaries

* fix(markdown): retain whitespace across rendered chunks

* fix(telegram): preserve links in plain fallbacks

* fix(channels): preserve chunk boundary semantics

* test(sms): verify lossless chunk whitespace

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 11:18:17 -07:00
Peter Steinberger
44314c9451 refactor(channels): table-drive setup and control-plane helpers (#109028)
* refactor(channels): table-drive setup credentials, config schemas, doctor detectors, status issues

* refactor(channels): control-plane tables (rest)

* fix(plugin-sdk): refresh surface budgets after rebase

* style(plugin-sdk): format credential helpers

* fix(channels): preserve generic schema refinement types

* fix(channels): preserve schema input and output inference

* fix(clickclack): forward credential patch fields

* test(plugin-sdk): use redacted credential fixtures

* fix(plugin-sdk): refresh API baseline after inference fix

* fix(channels): keep multi-account envelope optional

* fix(channels): preserve policy validation invariants

* fix(extensions): remove stale awaits from file checks

* style(qqbot): format synchronous file check

* fix(config): refresh bundled channel metadata

* fix(qqbot): reject unsupported pairing policy
2026-07-16 07:17:01 -07:00
Eden
d572c5cb2d fix(line): run post-ack webhook processing on its own admitted work root (#107734)
* fix(line): run post-ack webhook processing on its own admitted work root

LINE acks the webhook and dispatches event processing fire-and-forget on
the same async chain. The HTTP request admission that chain inherited is
released as soon as the route handler returns, and a released admission
refuses subordinate queue work - so every LINE inbound agent turn fails
with "GatewayDrainingError: Gateway is draining; new tasks are not
accepted" even though the gateway is healthy. DMs, group mentions, and
postbacks are all affected; the user-visible symptom is the bot replying
"Sorry, I encountered an error processing your message." to everything.

Add runDetachedWebhookWork to the plugin-sdk webhook-request-guards
surface (a thin wrapper over the gateway independent-root continuation,
the same shape core uses in gateway/server/hooks.ts) and route all three
LINE ack-first dispatch sites through it: the gateway monitor handler
(the live path), and the createLineNodeWebhookHandler / Express
middleware handlers (public webhook building blocks an embedder can
register under the gateway). #65375 unified these three into one ack-first
pattern; keeping the detach consistent avoids re-introducing the same
latent defect in the two that are not on the live gateway path today.

The continuation is reserved synchronously while the request is still
admitted, so the detached processing stays accepted and a real restart
drain can wait for it instead of stranding it mid-turn.

Tests pin every layer: the guards suite proves detached post-ack work is
admitted after the request admission is released (and that the inherited
chain without the helper is refused); the monitor lifecycle suite and the
webhook-node suite assert each dispatch site goes through the detached
root. Red/green verified: reverting any dispatch fails its test.

* fix(plugin-sdk): account for runDetachedWebhookWork in public surface budget

* fix(channels): track detached webhook processing

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

* docs: refresh generated docs map

* chore(plugin-sdk): refresh API baseline

* fix(webhooks): preserve post-ack ordering

* test(plugin-sdk): satisfy detached work lint

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 03:39:02 -07:00
Peter Steinberger
b93f4bb3ac refactor: privatize Twitch and SMS internals (#107737)
* refactor(twitch): privatize internal plugin surfaces

* refactor(sms): privatize internal plugin surfaces

* chore(deadcode): refresh unused-export baseline
2026-07-14 12:55:35 -07:00
snowzlmbot
e8ad0466ff fix: render assistant transcript headers safely (#99404)
* fix: render assistant transcript headers safely

Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>

* fix(markdown): nest crossing annotation spans

* fix(markdown): protect final transport projections

* refactor(markdown): split transcript render ownership

* test(ui): cover assistant transcript render flag

* refactor(markdown): keep transcript helpers private

* docs(changelog): note assistant transcript headers

* chore(plugin-sdk): refresh transcript annotation baseline

* fix(markdown): harden final transcript projections

* docs(changelog): defer transcript note to release

* refactor(markdown): centralize HTML tokenization

* fix(markdown): satisfy lint gates

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: snowzlmbot <293528334+snowzlmbot@users.noreply.github.com>
2026-07-14 02:25:37 -07:00
Peter Steinberger
9b565e8d50 refactor(plugins): trim long-tail dead exports (#106230)
* refactor(extensions): trim long-tail plugin exports

* refactor(whatsapp): remove dead media relay
2026-07-13 02:34:06 -07:00
Peter Steinberger
83bf0379c9 refactor(channels): share plugin contract scaffolds (#105838)
* refactor(channels): share plugin contract scaffolds

* fix: preserve channel config hint metadata

* chore: refresh Plugin SDK API baseline

* ci: refresh plugin SDK surface budget

* fix(ci): allow read-only state database boundary

* fix(ci): dedupe read-only state database boundary
2026-07-13 01:51:32 -07:00
Vincent Koc
2454511480 refactor(sms): consolidate webhook test hooks (#106072) 2026-07-13 14:02:10 +08:00
Peter Steinberger
807491e0f1 ci: consolidate SMS webhook test reset (#106070)
* ci: clear stale dead-export surfaces

* ci: align dead-export baseline
2026-07-12 22:41:35 -07:00
Peter Steinberger
1edc8b6c27 refactor(security): centralize timing-safe secret comparisons (#105989)
* refactor(plugins): reuse safe secret comparator

* refactor(security): centralize remaining secret comparisons

* chore(ci): lower refactored file baselines
2026-07-12 22:37:21 -07:00
Pavan Kumar Gondhi
ef9383d88a fix: protect SMS webhook callback quota [AI] (#103620)
* fix: scope SMS webhook rate limiting after validation

* fix: separate SMS webhook validation throttles

* fix: loosen SMS pre-validation throttle

* docs: clarify SMS webhook quota stages

* fix: preserve signed sms callback capacity

* fix: name sms invalid request limiter

* test: cover sms validation disabled quota

* fix: skip signed limiter without sms validation

* docs: clarify sms webhook request budget

* fix: keep sms disabled validation dispatch cap
2026-07-13 10:29:59 +05:30
Peter Steinberger
81941f2d68 test: enable noUncheckedIndexedAccess for extension tests (#105343) 2026-07-12 12:48:22 +01:00
Peter Steinberger
e34bff2276 refactor(plugin-sdk): collapse internal config-schema facade usage onto one module (#104665) 2026-07-11 13:00:53 -07:00
clawSean
e44f04c50e fix(sms): normalize Twilio RCS webhook senders (#102373)
Co-authored-by: clawSean <260045960+clawSean@users.noreply.github.com>
2026-07-10 17:51:47 -07:00
xingzhou
8d5f7e27b2 fix(sms): replayed Twilio webhooks process again after high inbound traffic (#101107)
* fix(sms): replayed Twilio webhooks process again after high inbound traffic

* fix(sms): harden Twilio replay saturation

* test(sms): expose response header spy

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-10 17:58:53 +01:00
Peter Steinberger
d185f9a0b4 fix(infra): preserve characters in truncated response snippets (#103136)
* fix(infra): preserve bounded response text characters

Co-authored-by: qingminlong <34085845+qingminglong@users.noreply.github.com>

* ci(plugin-sdk): refresh API baseline

---------

Co-authored-by: qingminlong <34085845+qingminglong@users.noreply.github.com>
2026-07-09 23:43:26 +01:00
Peter Steinberger
a2a68d154b fix(agent): preserve explicit recipient sessions (#101507)
* fix(agent): honor recipient session routing

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: pingfanfan <pingfan.work@gmail.com>

* fix(agent): preserve canonical recipient routes

* fix(agent): require exact recipient routes

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>

Co-authored-by: pingfanfan <pingfan.work@gmail.com>

* fix(agent): harden recipient route resolution

* fix(imessage): require canonical recipient handles

* fix(agent): refine provider recipient exactness

* fix(agent): bound direct alias session routing

* fix(signal): preserve direct alias route type

* fix(agent): honor binding-scoped recipient sessions

* fix(routing): honor configured main session aliases

* fix(clickclack): align account-owned session routes

* fix(twitch): preserve canonical recipient sessions

* fix(routing): isolate stable outbound identities

* chore: defer recipient session changelog

* fix(sms): use dedicated channel SDK facade

---------

Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: pingfanfan <pingfan.work@gmail.com>
2026-07-07 10:07:13 +01:00
Vincent Koc
1aeed5ec26 refactor(plugins): localize private config types (#101452) 2026-07-07 00:34:46 -07:00
clawSean
d84aabf642 feat: add channel pairing request hook (#97733)
* feat: add channel pairing request hook

* fix(plugin-sdk): keep pairing hook types internal

* docs: regenerate docs map

* docs: regenerate docs map

* docs: regenerate docs map

* fix(plugin-sdk): keep pairing hook types internal

* fix(plugin-sdk): keep pairing hook types internal

* docs: refresh plugin hook docs

* docs: refresh plugin hook docs

* docs: refresh plugin hook docs

---------

Co-authored-by: clawSean <260045960+clawSean@users.noreply.github.com>
Co-authored-by: Omar Shahine <omarshahine@users.noreply.github.com>
2026-07-05 19:11:58 -07:00
Wynne668
06b841fa58 fix(sms): strip internal tool traces from replies 2026-07-01 04:12:55 -07:00
lsr911
6e98477ee4 fix(sms): guard Twilio JSON.parse against malformed API response bodies (#97999)
Wrap JSON.parse in parseTwilioListPayload and retrieveTwilioMessagingService with try/catch to prevent a malformed Twilio API response from throwing an unhandled SyntaxError.

- parseTwilioListPayload: return [] on parse failure (fail-safe for phone number listing)
- retrieveTwilioMessagingService: throw descriptive Error on parse failure

Note: parseTwilioApiError and parseTwilioSuccessPayload already had try/catch guards (lines 85-97, 104-121).

Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-30 18:15:08 -07:00
Vincent Koc
f29af26326 fix(sms): bound twilio api response bodies 2026-06-19 13:24:16 +02:00
Peter Steinberger
4fa5092cdc docs: document small extension sources 2026-06-04 21:02:07 -04:00
Kevin Lin
fce002ad03 revert(codex): revert first-party marketplace allowlist
Reverts openclaw/openclaw#82219.
2026-06-03 15:35:35 -07:00
Peter Steinberger
b653d94918 chore(lint): enable no-useless-assignment 2026-05-31 22:40:48 +01:00
Peter Steinberger
304e2c83c0 chore(lint): enable stricter oxlint rules 2026-05-31 18:59:02 +01:00
clawSean
51228aecd4 fix(sms): cover native proof follow-ups (#88601)
Remove the duplicate plain approve command from pairing replies so SMS/native pairing shows one copyable owner approval command in the fenced block.

Add regression coverage for the single approve-command occurrence, plus Twilio guarded-egress release coverage for non-2xx and malformed-success send responses.

Verification:
- pnpm exec oxfmt --check src/pairing/pairing-messages.ts src/pairing/pairing-messages.test.ts extensions/sms/src/twilio.test.ts
- node scripts/run-vitest.mjs src/pairing/pairing-messages.test.ts src/pairing/pairing-challenge.test.ts src/plugin-sdk/channel-pairing.test.ts
- node scripts/run-vitest.mjs extensions/sms/src/twilio.test.ts

Thanks @clawSean.
2026-05-31 16:41:24 +01:00
Peter Steinberger
1e08af453a fix(sms): add Twilio webhook diagnostics
* fix(sms): diagnose Twilio webhook setup

* test(sms): satisfy diagnostic lint gates

* fix(sms): redact recent probe participants

* docs(sms): refresh SecretRef credential matrix

* fix(sms): probe Messaging Service webhooks

* fix(sms): resolve env-backed SecretRefs
2026-05-31 11:44:39 +01:00
Peter Steinberger
77f1359612 refactor: extract media and ACP core packages (#88534)
* refactor: extract media and acp core packages

* refactor: remove relocated media and acp sources

* build: wire new core packages into dependency checks

* test: alias new core packages in vitest

* build: keep media sniffer runtime dependency

* docs: refresh plugin sdk api baseline

* fix: keep normalized proposal queries non-empty

* test: keep channel timer tests isolated

* fix: keep rebased plugin checks green

* fix: preserve sms numeric allowlist entries

* test: harden exec foreground timeout failure

* test: remove duplicate skill workshop assertion

* fix: remove channel config lint suppression

* test: refresh lint suppression allowlist
2026-05-31 11:30:33 +01:00
Soham Patankar
4f3d8a57dd fix(codex): accept first-party OpenAI plugin marketplaces
Allow Codex native plugin config to target first-party OpenAI marketplaces, including openai-curated, openai-bundled, and openai-primary-runtime.

Fixes #82216.
Thanks @yaanfpv for the contribution.

Verification:
- node scripts/run-vitest.mjs test/scripts/lint-suppressions.test.ts
- pnpm build:ci-artifacts
- OPENCLAW_VITEST_MAX_WORKERS=2 node scripts/run-vitest.mjs run --config test/vitest/vitest.full-core-support-boundary.config.ts test/scripts/lint-suppressions.test.ts
- node scripts/run-vitest.mjs extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/plugin-activation.test.ts extensions/codex/src/app-server/session-binding.test.ts extensions/codex/src/migration/provider.test.ts extensions/sms/src/channel.test.ts extensions/sms/src/inbound.test.ts
- git diff --check
- ./.agents/skills/autoreview/scripts/autoreview --mode local
- GitHub PR CI on head 896640060b, including build-artifacts run 26709647050
2026-05-31 11:08:42 +01:00
tanshanshan
425a4ab2f2 chore(lint): enable object-shorthand (#81808)
* fix: narrow current-main core type guards

* fix: preserve query and test guard narrowing

* fix(copilot): align client options with sdk rename

* test(sms): type fetch mocks

* fix(sms): preserve numeric allowlist entries

* test(sms): preserve pairing send count assertion

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-05-31 10:46:10 +01:00
shawnduggan
1d55caa162 fix(memory): respect QMD status timeout
Respect the configured QMD status timeout during vector availability probes and skip checkpoint-style session transcript exports while preserving valid session IDs that merely contain checkpoint words.

Includes maintainer fixups for latest-main timer-dependent CI and SMS status/test drift.

Thanks @shawnduggan.

Verification:
- `mise exec node@24.13.0 -- node scripts/run-vitest.mjs run --config test/vitest/vitest.agents-core.config.ts src/agents/bash-tools.exec-foreground-failures.test.ts --maxWorkers=1`
- `mise exec node@24.16.0 -- node scripts/run-vitest.mjs run src/channels/draft-stream-loop.test.ts --maxWorkers=1`
- `mise exec node@24.16.0 -- node scripts/run-vitest.mjs run extensions/sms/src/channel.test.ts extensions/sms/src/inbound.test.ts extensions/sms/src/twilio.test.ts extensions/sms/src/gateway.test.ts --maxWorkers=1`
- `mise exec node@24.16.0 -- node scripts/run-vitest.mjs run --config test/vitest/vitest.gateway-server.config.ts src/gateway/server.agent.gateway-server-agent-b.test.ts --maxWorkers=1`
- `mise exec node@24.16.0 -- node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo`
- `mise exec node@24.16.0 -- node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo`
- `mise exec node@24.16.0 -- node scripts/run-oxlint-shards.mjs --threads=8`
- `git diff --check`
- GitHub Actions: run `26708853296` and required checks passed on `0c97217a9de501cb861fee731d5c008781da056c`.
2026-05-31 10:29:45 +01:00
Peter Steinberger
3258338ec8 chore(lint): clean sms lint fallout 2026-05-31 10:04:48 +01:00
Peter Steinberger
3a4943ef87 fix(ci): repair sms channel checks 2026-05-31 05:02:18 -04:00
Peter Steinberger
3513e8bfd9 feat: add Twilio SMS channel
Add a bundled SMS channel backed by Twilio inbound webhooks and outbound text delivery.

Includes signed webhook validation, pairing/allowlist access, Messaging Service sender support, chunked plain-text SMS delivery, default target support, docs, config metadata, labeler updates, and focused SMS coverage.

Verification:
- pnpm exec tsgo -p extensions/sms/tsconfig.json --noEmit
- OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-sms-land-fix2 node scripts/run-vitest.mjs extensions/sms/src/phone.test.ts extensions/sms/src/accounts.test.ts extensions/sms/src/twilio.test.ts extensions/sms/src/inbound.test.ts extensions/sms/src/gateway.test.ts extensions/sms/src/channel.test.ts extensions/sms/src/send.test.ts extensions/sms/src/webhook.test.ts --reporter=verbose
- pnpm config:channels:check
- pnpm plugins:inventory:check
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main
2026-05-31 09:22:31 +01:00