refactor(channels): own the lifecycle status contract in SDK patch factories (#118795)

* refactor(sdk): add channel lifecycle patch factories

* refactor(channels): adopt lifecycle patches in a-m

* refactor(channels): adopt lifecycle patches in n-z

* refactor(runtime): lifecycle-own ambient registries

* test(slack): assert lifecycle factory fields

* fix(sdk): preserve lifecycle patch extras types

* test(zalouser): widen lifecycle status sink

* test(irc): avoid shadowed status patch

* fix(zalo): reuse account-agnostic media route

* fix(gateway): accept explicit channel ready recovery

* test(qa): assert terminal Slack block fact

* test(qa): restore Slack blocked lifecycle scenario

* test(gateway): lock explicit lifecycle recovery contract
This commit is contained in:
Peter Steinberger
2026-08-03 12:39:48 -07:00
committed by GitHub
parent c218c539ab
commit f9d9d1225a
66 changed files with 805 additions and 381 deletions
+14 -17
View File
@@ -1,6 +1,11 @@
// Sms plugin module implements gateway behavior.
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/channel-contract";
import { waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
import {
channelBlockedPatch,
channelReadyPatch,
channelStoppedPatch,
} from "openclaw/plugin-sdk/gateway-runtime";
import { registerPluginHttpRoute } from "openclaw/plugin-sdk/webhook-ingress";
import { createSmsIngressSpool, type SmsIngressLog } from "./ingress-spool.js";
import type { ResolvedSmsAccount } from "./types.js";
@@ -160,7 +165,7 @@ export async function startSmsGatewayAccount(params: {
params.statusSink?.({ lifecycle: "starting" });
if (!params.account.enabled) {
params.log?.info?.(`SMS account ${params.account.accountId} is disabled`);
params.statusSink?.({ running: false, connected: false, lifecycle: "stopped" });
params.statusSink?.(channelStoppedPatch());
return waitUntilAbort(params.abortSignal);
}
const warnings = collectSmsStartupWarnings(params.account);
@@ -168,13 +173,12 @@ export async function startSmsGatewayAccount(params: {
for (const warning of warnings) {
params.log?.warn?.(warning);
}
params.statusSink?.({
running: true,
connected: false,
lifecycle: "blocked",
terminalDisconnect: true,
lastError: warnings.join("; "),
});
params.statusSink?.(
channelBlockedPatch(warnings.join("; "), {
running: true,
connected: false,
}),
);
return waitUntilAbort(params.abortSignal);
}
for (const warning of warnings) {
@@ -185,16 +189,9 @@ export async function startSmsGatewayAccount(params: {
params.log?.info?.(
`Registered SMS webhook route ${params.account.webhookPath} for account ${params.account.accountId}`,
);
params.statusSink?.({
running: true,
connected: true,
lifecycle: "ready",
lastConnectedAt: Date.now(),
lastError: null,
terminalDisconnect: undefined,
});
params.statusSink?.(channelReadyPatch());
}
return registration.lifecycle.finally(() => {
params.statusSink?.({ running: false, connected: false, lifecycle: "stopped" });
params.statusSink?.(channelStoppedPatch());
});
}