feat: loadable openclaw channel plugin v1 (agent=account)
Rewritten against the real openclaw v2026.5.7 plugin SDK (generic third-party channel path): createChannelPluginBase + createChatChannelPlugin with required capabilities, minimal ChannelSetupAdapter, agent=account config resolution, attached outbound -> Fabric POST, inbound socket per account -> runtime.channel.turn (wakeup->admission). Compat notes mark SDK-coupled seams for future openclaw upgrades. Verified: builds clean, installs, 'openclaw channels list' -> Fabric installed/configured/enabled. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
src/accounts.ts
Normal file
71
src/accounts.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
// agent = openclaw channel account.
|
||||
// Config shape:
|
||||
// channels.fabric.centerApiBase = "http://localhost:7001/api" (shared)
|
||||
// channels.fabric.accounts.<agentId> = { fabricApiKey, centerApiBase? }
|
||||
// Each account id IS the openclaw agentId that owns that Fabric identity.
|
||||
|
||||
export type FabricAccountConfig = {
|
||||
fabricApiKey?: string;
|
||||
centerApiBase?: string;
|
||||
enabled?: boolean;
|
||||
allowFrom?: string[];
|
||||
dmPolicy?: string;
|
||||
};
|
||||
|
||||
export type FabricChannelConfig = {
|
||||
centerApiBase?: string;
|
||||
accounts?: Record<string, FabricAccountConfig>;
|
||||
defaultAccount?: string;
|
||||
} & FabricAccountConfig;
|
||||
|
||||
type Cfg = { channels?: { fabric?: FabricChannelConfig }; [k: string]: unknown };
|
||||
|
||||
export type ResolvedFabricAccount = {
|
||||
accountId: string;
|
||||
enabled: boolean;
|
||||
centerApiBase: string;
|
||||
fabricApiKey: string;
|
||||
allowFrom: string[];
|
||||
dmPolicy: string | undefined;
|
||||
};
|
||||
|
||||
const DEFAULT_CENTER = 'http://localhost:7001/api';
|
||||
|
||||
function section(cfg: Cfg): FabricChannelConfig {
|
||||
return cfg.channels?.fabric ?? {};
|
||||
}
|
||||
|
||||
export function listFabricAccountIds(cfg: Cfg): string[] {
|
||||
const accts = section(cfg).accounts ?? {};
|
||||
const ids = Object.keys(accts);
|
||||
return ids.length ? ids : ['default'];
|
||||
}
|
||||
|
||||
export function resolveDefaultFabricAccountId(cfg: Cfg): string {
|
||||
const s = section(cfg);
|
||||
if (s.defaultAccount) return s.defaultAccount;
|
||||
const ids = listFabricAccountIds(cfg);
|
||||
return ids[0] ?? 'default';
|
||||
}
|
||||
|
||||
export function resolveFabricAccount(cfg: Cfg, accountId?: string | null): ResolvedFabricAccount {
|
||||
const s = section(cfg);
|
||||
const id = accountId ?? resolveDefaultFabricAccountId(cfg);
|
||||
const acc = s.accounts?.[id] ?? {};
|
||||
const fabricApiKey = (acc.fabricApiKey ?? '').trim();
|
||||
const centerApiBase = (acc.centerApiBase ?? s.centerApiBase ?? DEFAULT_CENTER).trim();
|
||||
return {
|
||||
accountId: id,
|
||||
enabled: acc.enabled !== false && s.enabled !== false,
|
||||
centerApiBase,
|
||||
fabricApiKey,
|
||||
allowFrom: acc.allowFrom ?? s.allowFrom ?? [],
|
||||
dmPolicy: acc.dmPolicy ?? s.dmPolicy,
|
||||
};
|
||||
}
|
||||
|
||||
export function listEnabledFabricAccounts(cfg: Cfg): ResolvedFabricAccount[] {
|
||||
return listFabricAccountIds(cfg)
|
||||
.map((id) => resolveFabricAccount(cfg, id))
|
||||
.filter((a) => a.enabled && a.fabricApiKey);
|
||||
}
|
||||
Reference in New Issue
Block a user