mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-16 12:30:49 +00:00
refactor: drop channel onboarding fallback
This commit is contained in:
@@ -1437,16 +1437,6 @@ Preferred setup split:
|
||||
- `plugin.setup` owns account-id normalization, validation, and config writes.
|
||||
- `plugin.setupWizard` lets the host run the common wizard flow while the channel only supplies status, credential, DM allowlist, and channel-access descriptors.
|
||||
|
||||
Use `plugin.onboarding` only when the host-owned setup wizard cannot express the flow and the
|
||||
channel needs to fully own prompting.
|
||||
|
||||
Wizard precedence:
|
||||
|
||||
1. `plugin.setupWizard` (preferred, host-owned prompts)
|
||||
2. `plugin.onboarding.configureInteractive`
|
||||
3. `plugin.onboarding.configureWhenConfigured` (already-configured channel only)
|
||||
4. `plugin.onboarding.configure`
|
||||
|
||||
`plugin.setupWizard` is best for channels that fit the shared pattern:
|
||||
|
||||
- one account picker driven by `plugin.config.listAccountIds`
|
||||
@@ -1458,11 +1448,6 @@ Wizard precedence:
|
||||
- optional DM allowlist resolution (for example `@username` -> numeric id)
|
||||
- optional completion note after setup finishes
|
||||
|
||||
`plugin.onboarding` hooks still return the same values as before:
|
||||
|
||||
- `"skip"` leaves selection and account tracking unchanged.
|
||||
- `{ cfg, accountId? }` applies config updates and records account selection.
|
||||
|
||||
### Write a new messaging channel (step‑by‑step)
|
||||
|
||||
Use this when you want a **new chat surface** (a "messaging channel"), not a model provider.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { ChannelOnboardingAdapter } from "./onboarding-types.js";
|
||||
import type { ChannelSetupWizard } from "./setup-wizard.js";
|
||||
import type {
|
||||
ChannelAuthAdapter,
|
||||
@@ -57,8 +56,6 @@ export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknow
|
||||
};
|
||||
};
|
||||
reload?: { configPrefixes: string[]; noopPrefixes?: string[] };
|
||||
// CLI onboarding wizard hooks for this channel.
|
||||
onboarding?: ChannelOnboardingAdapter;
|
||||
setupWizard?: ChannelSetupWizard;
|
||||
config: ChannelConfigAdapter<ResolvedAccount>;
|
||||
configSchema?: ChannelConfigSchema;
|
||||
|
||||
@@ -472,15 +472,17 @@ describe("setupChannels", () => {
|
||||
)?.accounts?.[accountId] ?? { accountId },
|
||||
setAccountEnabled,
|
||||
},
|
||||
onboarding: {
|
||||
getStatus: vi.fn(async ({ cfg }: { cfg: OpenClawConfig }) => ({
|
||||
channel: "msteams",
|
||||
configured: Boolean(
|
||||
(cfg.channels?.msteams as { tenantId?: string } | undefined)?.tenantId,
|
||||
),
|
||||
statusLines: [],
|
||||
selectionHint: "configured",
|
||||
})),
|
||||
setupWizard: {
|
||||
channel: "msteams",
|
||||
status: {
|
||||
configuredLabel: "configured",
|
||||
unconfiguredLabel: "needs setup",
|
||||
resolveConfigured: ({ cfg }: { cfg: OpenClawConfig }) =>
|
||||
Boolean((cfg.channels?.msteams as { tenantId?: string } | undefined)?.tenantId),
|
||||
resolveStatusLines: async () => [],
|
||||
resolveSelectionHint: async () => "configured",
|
||||
},
|
||||
credentials: [],
|
||||
},
|
||||
outbound: { deliveryMode: "direct" },
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
getChannelSetupPlugin,
|
||||
listChannelSetupPlugins,
|
||||
} from "../channels/plugins/setup-registry.js";
|
||||
import { buildChannelOnboardingAdapterFromSetupWizard } from "../channels/plugins/setup-wizard.js";
|
||||
import type { ChannelMeta, ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import {
|
||||
formatChannelPrimerLine,
|
||||
@@ -354,7 +355,14 @@ export async function setupChannels(
|
||||
if (adapter) {
|
||||
return adapter;
|
||||
}
|
||||
return scopedPluginsById.get(channel)?.onboarding;
|
||||
const scopedPlugin = scopedPluginsById.get(channel);
|
||||
if (!scopedPlugin?.setupWizard) {
|
||||
return undefined;
|
||||
}
|
||||
return buildChannelOnboardingAdapterFromSetupWizard({
|
||||
plugin: scopedPlugin,
|
||||
wizard: scopedPlugin.setupWizard,
|
||||
});
|
||||
};
|
||||
const preloadConfiguredExternalPlugins = () => {
|
||||
// Keep onboarding memory bounded by snapshot-loading only configured external plugins.
|
||||
|
||||
@@ -60,9 +60,6 @@ function resolveChannelOnboardingAdapter(
|
||||
setupWizardAdapters.set(plugin, adapter);
|
||||
return adapter;
|
||||
}
|
||||
if (plugin.onboarding) {
|
||||
return plugin.onboarding;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,12 @@ describe("plugin-sdk subpath exports", () => {
|
||||
expect("resolveWhatsAppMentionStripPatterns" in whatsappSdk).toBe(false);
|
||||
});
|
||||
|
||||
it("exports Feishu helpers", async () => {
|
||||
const feishuSdk = await import("openclaw/plugin-sdk/feishu");
|
||||
expect(typeof feishuSdk.feishuSetupWizard).toBe("object");
|
||||
expect(typeof feishuSdk.feishuSetupAdapter).toBe("object");
|
||||
});
|
||||
|
||||
it("exports LINE helpers", () => {
|
||||
expect(typeof lineSdk.processLineMessage).toBe("function");
|
||||
expect(typeof lineSdk.createInfoCard).toBe("function");
|
||||
@@ -109,6 +115,8 @@ describe("plugin-sdk subpath exports", () => {
|
||||
it("exports Microsoft Teams helpers", () => {
|
||||
expect(typeof msteamsSdk.resolveControlCommandGate).toBe("function");
|
||||
expect(typeof msteamsSdk.loadOutboundMediaFromUrl).toBe("function");
|
||||
expect(typeof msteamsSdk.msteamsSetupWizard).toBe("object");
|
||||
expect(typeof msteamsSdk.msteamsSetupAdapter).toBe("object");
|
||||
});
|
||||
|
||||
it("exports Google Chat helpers", async () => {
|
||||
@@ -117,6 +125,18 @@ describe("plugin-sdk subpath exports", () => {
|
||||
expect(typeof googlechatSdk.googlechatSetupAdapter).toBe("object");
|
||||
});
|
||||
|
||||
it("exports Zalo helpers", async () => {
|
||||
const zaloSdk = await import("openclaw/plugin-sdk/zalo");
|
||||
expect(typeof zaloSdk.zaloSetupWizard).toBe("object");
|
||||
expect(typeof zaloSdk.zaloSetupAdapter).toBe("object");
|
||||
});
|
||||
|
||||
it("exports Zalouser helpers", async () => {
|
||||
const zalouserSdk = await import("openclaw/plugin-sdk/zalouser");
|
||||
expect(typeof zalouserSdk.zalouserSetupWizard).toBe("object");
|
||||
expect(typeof zalouserSdk.zalouserSetupAdapter).toBe("object");
|
||||
});
|
||||
|
||||
it("exports Tlon helpers", async () => {
|
||||
const tlonSdk = await import("openclaw/plugin-sdk/tlon");
|
||||
expect(typeof tlonSdk.fetchWithSsrFGuard).toBe("function");
|
||||
@@ -142,6 +162,10 @@ describe("plugin-sdk subpath exports", () => {
|
||||
const bluebubbles = await import("openclaw/plugin-sdk/bluebubbles");
|
||||
expect(typeof bluebubbles.parseFiniteNumber).toBe("function");
|
||||
|
||||
const matrix = await import("openclaw/plugin-sdk/matrix");
|
||||
expect(typeof matrix.matrixSetupWizard).toBe("object");
|
||||
expect(typeof matrix.matrixSetupAdapter).toBe("object");
|
||||
|
||||
const mattermost = await import("openclaw/plugin-sdk/mattermost");
|
||||
expect(typeof mattermost.parseStrictPositiveInteger).toBe("function");
|
||||
|
||||
@@ -151,6 +175,8 @@ describe("plugin-sdk subpath exports", () => {
|
||||
const twitch = await import("openclaw/plugin-sdk/twitch");
|
||||
expect(typeof twitch.DEFAULT_ACCOUNT_ID).toBe("string");
|
||||
expect(typeof twitch.normalizeAccountId).toBe("function");
|
||||
expect(typeof twitch.twitchSetupWizard).toBe("object");
|
||||
expect(typeof twitch.twitchSetupAdapter).toBe("object");
|
||||
|
||||
const zalo = await import("openclaw/plugin-sdk/zalo");
|
||||
expect(typeof zalo.resolveClientIp).toBe("function");
|
||||
|
||||
Reference in New Issue
Block a user