fix(channels): add optional defaultAccount routing

This commit is contained in:
Peter Steinberger
2026-03-02 04:03:13 +00:00
parent 0437ac1a89
commit 41537e9303
45 changed files with 461 additions and 35 deletions

View File

@@ -37,6 +37,8 @@ const matrixRoomSchema = z
export const MatrixConfigSchema = z.object({
name: z.string().optional(),
enabled: z.boolean().optional(),
defaultAccount: z.string().optional(),
accounts: z.record(z.string(), z.unknown()).optional(),
markdown: MarkdownConfigSchema,
homeserver: z.string().optional(),
userId: z.string().optional(),

View File

@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { CoreConfig } from "../types.js";
import { resolveMatrixAccount } from "./accounts.js";
import { resolveDefaultMatrixAccountId, resolveMatrixAccount } from "./accounts.js";
vi.mock("./credentials.js", () => ({
loadMatrixCredentials: () => null,
@@ -80,3 +80,52 @@ describe("resolveMatrixAccount", () => {
expect(account.configured).toBe(true);
});
});
describe("resolveDefaultMatrixAccountId", () => {
it("prefers channels.matrix.defaultAccount when it matches a configured account", () => {
const cfg: CoreConfig = {
channels: {
matrix: {
defaultAccount: "alerts",
accounts: {
default: { homeserver: "https://matrix.example.org", accessToken: "tok-default" },
alerts: { homeserver: "https://matrix.example.org", accessToken: "tok-alerts" },
},
},
},
};
expect(resolveDefaultMatrixAccountId(cfg)).toBe("alerts");
});
it("normalizes channels.matrix.defaultAccount before lookup", () => {
const cfg: CoreConfig = {
channels: {
matrix: {
defaultAccount: "Team Alerts",
accounts: {
"team-alerts": { homeserver: "https://matrix.example.org", accessToken: "tok-alerts" },
},
},
},
};
expect(resolveDefaultMatrixAccountId(cfg)).toBe("team-alerts");
});
it("falls back when channels.matrix.defaultAccount is not configured", () => {
const cfg: CoreConfig = {
channels: {
matrix: {
defaultAccount: "missing",
accounts: {
default: { homeserver: "https://matrix.example.org", accessToken: "tok-default" },
alerts: { homeserver: "https://matrix.example.org", accessToken: "tok-alerts" },
},
},
},
};
expect(resolveDefaultMatrixAccountId(cfg)).toBe("default");
});
});

View File

@@ -1,4 +1,8 @@
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import {
DEFAULT_ACCOUNT_ID,
normalizeAccountId,
normalizeOptionalAccountId,
} from "openclaw/plugin-sdk/account-id";
import type { CoreConfig, MatrixConfig } from "../types.js";
import { resolveMatrixConfigForAccount } from "./client.js";
import { credentialsMatchConfig, loadMatrixCredentials } from "./credentials.js";
@@ -16,6 +20,7 @@ function mergeAccountConfig(base: MatrixConfig, account: MatrixConfig): MatrixCo
}
// Don't propagate the accounts map into the merged per-account config
delete (merged as Record<string, unknown>).accounts;
delete (merged as Record<string, unknown>).defaultAccount;
return merged;
}
@@ -54,6 +59,13 @@ export function listMatrixAccountIds(cfg: CoreConfig): string[] {
}
export function resolveDefaultMatrixAccountId(cfg: CoreConfig): string {
const preferred = normalizeOptionalAccountId(cfg.channels?.matrix?.defaultAccount);
if (
preferred &&
listMatrixAccountIds(cfg).some((accountId) => normalizeAccountId(accountId) === preferred)
) {
return preferred;
}
const ids = listMatrixAccountIds(cfg);
if (ids.includes(DEFAULT_ACCOUNT_ID)) {
return DEFAULT_ACCOUNT_ID;

View File

@@ -49,6 +49,8 @@ export type MatrixConfig = {
enabled?: boolean;
/** Multi-account configuration keyed by account ID. */
accounts?: Record<string, MatrixAccountConfig>;
/** Optional default account id when multiple accounts are configured. */
defaultAccount?: string;
/** Matrix homeserver URL (https://matrix.example.org). */
homeserver?: string;
/** Matrix user id (@user:server). */