Skip to content

Commit a17487b

Browse files
committed
refactor: share QA channel plugin base
1 parent f613f32 commit a17487b

3 files changed

Lines changed: 74 additions & 92 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { getChatChannelMeta } from "openclaw/plugin-sdk/channel-plugin-common";
2+
import {
3+
listQaChannelAccountIds,
4+
resolveDefaultQaChannelAccountId,
5+
resolveQaChannelAccount,
6+
type ResolvedQaChannelAccount,
7+
} from "./accounts.js";
8+
import { qaChannelPluginConfigSchema } from "./config-schema.js";
9+
import type { ChannelPlugin } from "./runtime-api.js";
10+
import { applyQaSetup } from "./setup.js";
11+
import type { CoreConfig } from "./types.js";
12+
13+
export const QA_CHANNEL_ID = "qa-channel" as const;
14+
15+
export const qaChannelSetupMeta = { ...getChatChannelMeta(QA_CHANNEL_ID) };
16+
export const qaChannelRuntimeMeta = {
17+
...qaChannelSetupMeta,
18+
id: QA_CHANNEL_ID,
19+
label: "QA Channel",
20+
selectionLabel: "QA Channel",
21+
docsPath: "/channels/qa-channel",
22+
blurb: "Synthetic QA channel for OpenClaw QA runs.",
23+
};
24+
25+
type QaChannelPluginBase = Pick<
26+
ChannelPlugin<ResolvedQaChannelAccount>,
27+
"id" | "meta" | "capabilities" | "reload" | "configSchema" | "setup" | "config"
28+
>;
29+
30+
export function createQaChannelPluginBase(
31+
meta: ChannelPlugin<ResolvedQaChannelAccount>["meta"] = qaChannelSetupMeta,
32+
): QaChannelPluginBase {
33+
return {
34+
id: QA_CHANNEL_ID,
35+
meta,
36+
capabilities: {
37+
chatTypes: ["direct", "group"],
38+
},
39+
reload: { configPrefixes: ["channels.qa-channel"] },
40+
configSchema: qaChannelPluginConfigSchema,
41+
setup: {
42+
applyAccountConfig: ({ cfg, accountId, input }) =>
43+
applyQaSetup({
44+
cfg,
45+
accountId,
46+
input: input as Record<string, unknown>,
47+
}),
48+
},
49+
config: {
50+
listAccountIds: (cfg) => listQaChannelAccountIds(cfg as CoreConfig),
51+
resolveAccount: (cfg, accountId) =>
52+
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }),
53+
defaultAccountId: (cfg) => resolveDefaultQaChannelAccountId(cfg as CoreConfig),
54+
isConfigured: (account) => account.configured,
55+
resolveAllowFrom: ({ cfg, accountId }) =>
56+
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }).config.allowFrom,
57+
resolveDefaultTo: ({ cfg, accountId }) =>
58+
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }).config.defaultTo,
59+
},
60+
};
61+
}
Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,6 @@
1-
import { getChatChannelMeta } from "openclaw/plugin-sdk/channel-plugin-common";
2-
import {
3-
listQaChannelAccountIds,
4-
resolveDefaultQaChannelAccountId,
5-
resolveQaChannelAccount,
6-
type ResolvedQaChannelAccount,
7-
} from "./accounts.js";
8-
import { qaChannelPluginConfigSchema } from "./config-schema.js";
1+
import type { ResolvedQaChannelAccount } from "./accounts.js";
2+
import { createQaChannelPluginBase } from "./channel-base.js";
93
import type { ChannelPlugin } from "./runtime-api.js";
10-
import { applyQaSetup } from "./setup.js";
11-
import type { CoreConfig } from "./types.js";
124

13-
const CHANNEL_ID = "qa-channel" as const;
14-
const meta = { ...getChatChannelMeta(CHANNEL_ID) };
15-
16-
export const qaChannelSetupPlugin: ChannelPlugin<ResolvedQaChannelAccount> = {
17-
id: CHANNEL_ID,
18-
meta,
19-
capabilities: {
20-
chatTypes: ["direct", "group"],
21-
},
22-
reload: { configPrefixes: ["channels.qa-channel"] },
23-
configSchema: qaChannelPluginConfigSchema,
24-
setup: {
25-
applyAccountConfig: ({ cfg, accountId, input }) =>
26-
applyQaSetup({
27-
cfg,
28-
accountId,
29-
input: input as Record<string, unknown>,
30-
}),
31-
},
32-
config: {
33-
listAccountIds: (cfg) => listQaChannelAccountIds(cfg as CoreConfig),
34-
resolveAccount: (cfg, accountId) =>
35-
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }),
36-
defaultAccountId: (cfg) => resolveDefaultQaChannelAccountId(cfg as CoreConfig),
37-
isConfigured: (account) => account.configured,
38-
resolveAllowFrom: ({ cfg, accountId }) =>
39-
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }).config.allowFrom,
40-
resolveDefaultTo: ({ cfg, accountId }) =>
41-
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }).config.defaultTo,
42-
},
43-
};
5+
export const qaChannelSetupPlugin: ChannelPlugin<ResolvedQaChannelAccount> =
6+
createQaChannelPluginBase();

extensions/qa-channel/src/channel.ts

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,18 @@ import {
77
createMessageReceiptFromOutboundResults,
88
defineChannelMessageAdapter,
99
} from "openclaw/plugin-sdk/channel-outbound";
10-
import { getChatChannelMeta } from "openclaw/plugin-sdk/channel-plugin-common";
11-
import {
12-
DEFAULT_ACCOUNT_ID,
13-
listQaChannelAccountIds,
14-
resolveDefaultQaChannelAccountId,
15-
resolveQaChannelAccount,
16-
} from "./accounts.js";
10+
import { DEFAULT_ACCOUNT_ID } from "./accounts.js";
1711
import { buildQaTarget, normalizeQaTarget, parseQaTarget } from "./bus-client.js";
1812
import { qaChannelMessageActions } from "./channel-actions.js";
19-
import { qaChannelPluginConfigSchema } from "./config-schema.js";
13+
import { createQaChannelPluginBase, QA_CHANNEL_ID, qaChannelRuntimeMeta } from "./channel-base.js";
2014
import { startQaGatewayAccount } from "./gateway.js";
2115
import { sendQaChannelText } from "./outbound.js";
2216
import type { ChannelPlugin } from "./runtime-api.js";
23-
import { applyQaSetup } from "./setup.js";
2417
import { qaChannelStatus } from "./status.js";
2518
import type { CoreConfig, ResolvedQaChannelAccount } from "./types.js";
2619

27-
const CHANNEL_ID = "qa-channel" as const;
28-
const meta = {
29-
...getChatChannelMeta(CHANNEL_ID),
30-
id: CHANNEL_ID,
31-
label: "QA Channel",
32-
selectionLabel: "QA Channel",
33-
docsPath: "/channels/qa-channel",
34-
blurb: "Synthetic QA channel for OpenClaw QA runs.",
35-
};
36-
3720
const qaChannelMessageAdapter = defineChannelMessageAdapter({
38-
id: CHANNEL_ID,
21+
id: QA_CHANNEL_ID,
3922
durableFinal: {
4023
capabilities: {
4124
text: true,
@@ -59,7 +42,7 @@ const qaChannelMessageAdapter = defineChannelMessageAdapter({
5942
return {
6043
messageId: result.messageId,
6144
receipt: createMessageReceiptFromOutboundResults({
62-
results: [{ channel: CHANNEL_ID, messageId: result.messageId }],
45+
results: [{ channel: QA_CHANNEL_ID, messageId: result.messageId }],
6346
threadId,
6447
replyToId,
6548
kind: "text",
@@ -71,32 +54,7 @@ const qaChannelMessageAdapter = defineChannelMessageAdapter({
7154

7255
export const qaChannelPlugin: ChannelPlugin<ResolvedQaChannelAccount> = createChatChannelPlugin({
7356
base: {
74-
id: CHANNEL_ID,
75-
meta,
76-
capabilities: {
77-
chatTypes: ["direct", "group"],
78-
},
79-
reload: { configPrefixes: ["channels.qa-channel"] },
80-
configSchema: qaChannelPluginConfigSchema,
81-
setup: {
82-
applyAccountConfig: ({ cfg, accountId, input }) =>
83-
applyQaSetup({
84-
cfg,
85-
accountId,
86-
input: input as Record<string, unknown>,
87-
}),
88-
},
89-
config: {
90-
listAccountIds: (cfg) => listQaChannelAccountIds(cfg as CoreConfig),
91-
resolveAccount: (cfg, accountId) =>
92-
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }),
93-
defaultAccountId: (cfg) => resolveDefaultQaChannelAccountId(cfg as CoreConfig),
94-
isConfigured: (account) => account.configured,
95-
resolveAllowFrom: ({ cfg, accountId }) =>
96-
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }).config.allowFrom,
97-
resolveDefaultTo: ({ cfg, accountId }) =>
98-
resolveQaChannelAccount({ cfg: cfg as CoreConfig, accountId }).config.defaultTo,
99-
},
57+
...createQaChannelPluginBase(qaChannelRuntimeMeta),
10058
messaging: {
10159
normalizeTarget: normalizeQaTarget,
10260
inferTargetChatType: ({ to }) => parseQaTarget(to).chatType,
@@ -118,7 +76,7 @@ export const qaChannelPlugin: ChannelPlugin<ResolvedQaChannelAccount> = createCh
11876
const baseRoute = buildChannelOutboundSessionRoute({
11977
cfg,
12078
agentId,
121-
channel: CHANNEL_ID,
79+
channel: QA_CHANNEL_ID,
12280
accountId,
12381
peer: {
12482
kind:
@@ -130,7 +88,7 @@ export const qaChannelPlugin: ChannelPlugin<ResolvedQaChannelAccount> = createCh
13088
id: buildQaTarget(parsed),
13189
},
13290
chatType: parsed.chatType,
133-
from: `qa-channel:${accountId ?? DEFAULT_ACCOUNT_ID}`,
91+
from: `${QA_CHANNEL_ID}:${accountId ?? DEFAULT_ACCOUNT_ID}`,
13492
to: buildQaTarget(parsed),
13593
});
13694
return buildThreadAwareOutboundSessionRoute({
@@ -158,7 +116,7 @@ export const qaChannelPlugin: ChannelPlugin<ResolvedQaChannelAccount> = createCh
158116
status: qaChannelStatus,
159117
gateway: {
160118
startAccount: async (ctx) => {
161-
await startQaGatewayAccount(CHANNEL_ID, meta.label, ctx);
119+
await startQaGatewayAccount(QA_CHANNEL_ID, qaChannelRuntimeMeta.label, ctx);
162120
},
163121
},
164122
actions: qaChannelMessageActions,
@@ -169,7 +127,7 @@ export const qaChannelPlugin: ChannelPlugin<ResolvedQaChannelAccount> = createCh
169127
deliveryMode: "direct",
170128
},
171129
attachedResults: {
172-
channel: CHANNEL_ID,
130+
channel: QA_CHANNEL_ID,
173131
sendText: async ({ cfg, to, text, accountId, threadId, replyToId }) =>
174132
await sendQaChannelText({
175133
cfg: cfg as CoreConfig,

0 commit comments

Comments
 (0)