refactor: dedupe channel and gateway surfaces

This commit is contained in:
Peter Steinberger
2026-03-02 19:48:12 +00:00
parent 9617ac9dd5
commit 9d30159fcd
44 changed files with 1072 additions and 1479 deletions

View File

@@ -34,3 +34,38 @@ export function formatChannelAllowFrom(params: {
}
return params.allowFrom.map((entry) => String(entry).trim()).filter(Boolean);
}
function asRecord(value: unknown): Record<string, unknown> | undefined {
if (!value || typeof value !== "object") {
return undefined;
}
return value as Record<string, unknown>;
}
export function resolveChannelAccountEnabled(params: {
plugin: ChannelPlugin;
account: unknown;
cfg: OpenClawConfig;
}): boolean {
if (params.plugin.config.isEnabled) {
return params.plugin.config.isEnabled(params.account, params.cfg);
}
const enabled = asRecord(params.account)?.enabled;
return enabled !== false;
}
export async function resolveChannelAccountConfigured(params: {
plugin: ChannelPlugin;
account: unknown;
cfg: OpenClawConfig;
readAccountConfiguredField?: boolean;
}): Promise<boolean> {
if (params.plugin.config.isConfigured) {
return await params.plugin.config.isConfigured(params.account, params.cfg);
}
if (params.readAccountConfiguredField) {
const configured = asRecord(params.account)?.configured;
return configured !== false;
}
return true;
}

View File

@@ -4,6 +4,7 @@ import {
readStringArrayParam,
readStringParam,
} from "../../../../agents/tools/common.js";
import { readDiscordParentIdParam } from "../../../../agents/tools/discord-actions-shared.js";
import { handleDiscordAction } from "../../../../agents/tools/discord-actions.js";
import { resolveDiscordChannelId } from "../../../../discord/targets.js";
import type { ChannelMessageActionContext } from "../../types.js";
@@ -11,16 +12,6 @@ import { tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-a
const providerId = "discord";
function readParentIdParam(params: Record<string, unknown>): string | null | undefined {
if (params.clearParent === true) {
return null;
}
if (params.parentId === null) {
return null;
}
return readStringParam(params, "parentId");
}
export async function handleDiscordMessageAction(
ctx: Pick<
ChannelMessageActionContext,
@@ -285,7 +276,7 @@ export async function handleDiscordMessageAction(
const adminResult = await tryHandleDiscordMessageActionGuildAdmin({
ctx,
resolveChannelId,
readParentIdParam,
readParentIdParam: readDiscordParentIdParam,
});
if (adminResult !== undefined) {
return adminResult;

View File

@@ -0,0 +1,21 @@
import { resolveEnvelopeFormatOptions } from "../auto-reply/envelope.js";
import type { OpenClawConfig } from "../config/config.js";
import { readSessionUpdatedAt, resolveStorePath } from "../config/sessions.js";
export function resolveInboundSessionEnvelopeContext(params: {
cfg: OpenClawConfig;
agentId: string;
sessionKey: string;
}) {
const storePath = resolveStorePath(params.cfg.session?.store, {
agentId: params.agentId,
});
return {
storePath,
envelopeOptions: resolveEnvelopeFormatOptions(params.cfg),
previousTimestamp: readSessionUpdatedAt({
storePath,
sessionKey: params.sessionKey,
}),
};
}

View File

@@ -0,0 +1,24 @@
import type { MsgContext } from "../auto-reply/templating.js";
import type { OpenClawConfig } from "../config/config.js";
import { recordSessionMetaFromInbound, resolveStorePath } from "../config/sessions.js";
export async function recordInboundSessionMetaSafe(params: {
cfg: OpenClawConfig;
agentId: string;
sessionKey: string;
ctx: MsgContext;
onError?: (error: unknown) => void;
}): Promise<void> {
const storePath = resolveStorePath(params.cfg.session?.store, {
agentId: params.agentId,
});
try {
await recordSessionMetaFromInbound({
storePath,
sessionKey: params.sessionKey,
ctx: params.ctx,
});
} catch (err) {
params.onError?.(err);
}
}

View File

@@ -84,6 +84,52 @@ export function parseTargetPrefixes(params: {
return undefined;
}
export function parseAtUserTarget(params: {
raw: string;
pattern: RegExp;
errorMessage: string;
}): MessagingTarget | undefined {
if (!params.raw.startsWith("@")) {
return undefined;
}
const candidate = params.raw.slice(1).trim();
const id = ensureTargetId({
candidate,
pattern: params.pattern,
errorMessage: params.errorMessage,
});
return buildMessagingTarget("user", id, params.raw);
}
export function parseMentionPrefixOrAtUserTarget(params: {
raw: string;
mentionPattern: RegExp;
prefixes: Array<{ prefix: string; kind: MessagingTargetKind }>;
atUserPattern: RegExp;
atUserErrorMessage: string;
}): MessagingTarget | undefined {
const mentionTarget = parseTargetMention({
raw: params.raw,
mentionPattern: params.mentionPattern,
kind: "user",
});
if (mentionTarget) {
return mentionTarget;
}
const prefixedTarget = parseTargetPrefixes({
raw: params.raw,
prefixes: params.prefixes,
});
if (prefixedTarget) {
return prefixedTarget;
}
return parseAtUserTarget({
raw: params.raw,
pattern: params.atUserPattern,
errorMessage: params.atUserErrorMessage,
});
}
export function requireTargetKind(params: {
platform: string;
target: MessagingTarget | undefined;