diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d0e1bbf57a..c43873db812 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Docs: https://docs.openclaw.ai - Google Meet: refresh realtime browser state during status and retry delayed speech after Meet finishes joining, so a just-opened in-call tab no longer leaves speech stuck behind stale `not-in-call` health. - Google Meet: grant Meet media permissions through the Playwright browser context when CDP grants do not affect the attached Chrome page, and report in-call microphone/speaker permission problems instead of marking realtime speech ready. +- Tlon: expose `groupInviteAllowlist` in the channel config schema and clarify that group invite auto-accept fails closed without an invite allowlist. Thanks @vincentkoc. - Google Chat: update the setup example to use the accepted `groups..enabled` key instead of the legacy `allow` alias, with a schema regression for the documented group shape. Thanks @vincentkoc. - Control UI/WebChat: collapse duplicate in-flight internal text sends onto the active Gateway run so rapid repeat submits do not start fresh `agent:main:main` dispatches. Fixes #75737. Thanks @dsdsddd1 and @BunsDev. - Mattermost: accept the documented `channels.mattermost.streaming` config and honor `streaming: "off"` by disabling draft preview posts. Thanks @vincentkoc. diff --git a/docs/.generated/config-baseline.sha256 b/docs/.generated/config-baseline.sha256 index b5e8112ab93..f19050e1a43 100644 --- a/docs/.generated/config-baseline.sha256 +++ b/docs/.generated/config-baseline.sha256 @@ -1,4 +1,4 @@ -5603f93164f1bed3b39714b813c7597e188321fff07cfbb6980d7198a69da162 config-baseline.json +e56c45e488ccd3a5849d170b3c696358f0c04c39d0d15b0a4ca47892e6eee0d0 config-baseline.json 5b5ebd95939d75496597d9858a375e27544812d0f79dc3b4bf87c794ada2ba08 config-baseline.core.json -c83a29196d34b4aff4849f63ae8850298441c367811d928e1ab2efe787eae520 config-baseline.channel.json +c2b5883fe161cd97b2787c92cf71726840de84d097d85d741791f523bd55a865 config-baseline.channel.json 055fae0d0067a751dc10125af7421da45633f73519c94c982d02b0c4eb2bdf67 config-baseline.plugin.json diff --git a/docs/channels/tlon.md b/docs/channels/tlon.md index b9d60ccdd53..2301b17de35 100644 --- a/docs/channels/tlon.md +++ b/docs/channels/tlon.md @@ -190,18 +190,22 @@ Auto-accept DM invites (for ships in dmAllowlist): } ``` -Auto-accept group invites: +Auto-accept group invites from trusted ships: ```json5 { channels: { tlon: { autoAcceptGroupInvites: true, + groupInviteAllowlist: ["~zod"], }, }, } ``` +`autoAcceptGroupInvites` fails closed when `groupInviteAllowlist` is empty. Set the +allowlist to the ships whose group invites should be accepted automatically. + ## Delivery targets (CLI/cron) Use these with `openclaw message send` or cron delivery: @@ -268,7 +272,8 @@ Provider options: - `channels.tlon.ownerShip`: owner ship for approval system (always authorized). - `channels.tlon.dmAllowlist`: ships allowed to DM (empty = none). - `channels.tlon.autoAcceptDmInvites`: auto-accept DMs from allowlisted ships. -- `channels.tlon.autoAcceptGroupInvites`: auto-accept all group invites. +- `channels.tlon.autoAcceptGroupInvites`: auto-accept group invites from allowlisted ships. +- `channels.tlon.groupInviteAllowlist`: ships whose group invites may be auto-accepted. - `channels.tlon.autoDiscoverChannels`: auto-discover group channels (default: true). - `channels.tlon.groupChannels`: manually pinned channel nests. - `channels.tlon.defaultAuthorizedShips`: ships authorized for all channels. diff --git a/extensions/tlon/src/config-schema.ts b/extensions/tlon/src/config-schema.ts index fe011fa2945..4d710784cb2 100644 --- a/extensions/tlon/src/config-schema.ts +++ b/extensions/tlon/src/config-schema.ts @@ -29,6 +29,7 @@ const tlonCommonConfigFields = { network: TlonNetworkSchema, groupChannels: z.array(ChannelNestSchema).optional(), dmAllowlist: z.array(ShipSchema).optional(), + groupInviteAllowlist: z.array(ShipSchema).optional(), autoDiscoverChannels: z.boolean().optional(), showModelSignature: z.boolean().optional(), responsePrefix: z.string().optional(), diff --git a/extensions/tlon/src/core.test.ts b/extensions/tlon/src/core.test.ts index 2e8cb870a9f..411a18e7c3d 100644 --- a/extensions/tlon/src/core.test.ts +++ b/extensions/tlon/src/core.test.ts @@ -101,6 +101,17 @@ describe("tlon core", () => { expect(parsed.accounts?.primary?.ship).toBe("~zod"); }); + it("exposes group invite allowlists in channel config schema", () => { + expect(TlonConfigSchema.parse({ groupInviteAllowlist: ["~zod"] }).groupInviteAllowlist).toEqual( + ["~zod"], + ); + expect( + TlonConfigSchema.parse({ + accounts: { primary: { groupInviteAllowlist: ["~nec"] } }, + }).accounts?.primary?.groupInviteAllowlist, + ).toEqual(["~nec"]); + }); + it("configures ship, auth, and discovery settings", async () => { const prompter = createTestWizardPrompter({ text: vi.fn(async ({ message }: { message: string }) => { diff --git a/src/config/bundled-channel-config-metadata.generated.ts b/src/config/bundled-channel-config-metadata.generated.ts index 60ce3e106a3..b1eb2092c9b 100644 --- a/src/config/bundled-channel-config-metadata.generated.ts +++ b/src/config/bundled-channel-config-metadata.generated.ts @@ -16353,6 +16353,13 @@ export const GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA = [ minLength: 1, }, }, + groupInviteAllowlist: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, autoDiscoverChannels: { type: "boolean", }, @@ -16455,6 +16462,13 @@ export const GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA = [ minLength: 1, }, }, + groupInviteAllowlist: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, autoDiscoverChannels: { type: "boolean", },