feishu, line: pass per-group systemPrompt to inbound context (#31713)

* feishu: pass per-group systemPrompt to inbound context

The Feishu extension schema supports systemPrompt in per-group config
(channels.feishu.accounts.<id>.groups.<groupId>.systemPrompt) but the
value was never forwarded to the inbound context as GroupSystemPrompt.

This means per-group system prompts configured for Feishu had no effect,
unlike IRC, Discord, Slack, Telegram, Matrix, and other channels that
already pass this field correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* line: pass per-group systemPrompt to inbound context

Same issue as feishu: the Line config schema defines systemPrompt in
per-group config but the value was never forwarded as GroupSystemPrompt
in the inbound context payload.

Added resolveLineGroupSystemPrompt helper that mirrors the existing
resolveLineGroupConfig lookup logic (groupId > roomId > wildcard).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Changelog: note Feishu and LINE group systemPrompt propagation

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
Tian Wei
2026-03-03 12:07:35 +08:00
committed by GitHub
parent d9d604c6ad
commit 7c179f9288
3 changed files with 20 additions and 1 deletions

View File

@@ -42,6 +42,7 @@ Docs: https://docs.openclaw.ai
- Plugin command/runtime hardening: validate and normalize plugin command name/description at registration boundaries, and guard Telegram native menu normalization paths so malformed plugin command specs cannot crash startup (`trim` on undefined). (#31997) Fixes #31944. Thanks @liuxiaopai-ai.
- Telegram: guard duplicate-token checks and gateway startup token normalization when account tokens are missing, preventing `token.trim()` crashes during status/start flows. (#31973) Thanks @ningding97.
- Discord/lifecycle startup status: push an immediate `connected` status snapshot when the gateway is already connected before lifecycle debug listeners attach, with abort-guarding to avoid contradictory status flips during pre-aborted startup. (#32336) Thanks @mitchmcalister.
- Feishu/LINE group system prompts: forward per-group `systemPrompt` config into inbound context `GroupSystemPrompt` for Feishu and LINE group/room events so configured group-specific behavior actually applies at dispatch time. (#31713) Thanks @whiskyboy.
- Mentions/Slack formatting hardening: add null-safe guards for runtime text normalization paths so malformed/undefined text payloads do not crash mention stripping or mrkdwn conversion. (#31865) Thanks @stone-jin.
- Feishu/Plugin sdk compatibility: add safe webhook default fallbacks when loading Feishu monitor state so mixed-version installs no longer crash if older `openclaw/plugin-sdk` builds omit webhook default constants. (#31606)
- Feishu/group broadcast dispatch: add configurable multi-agent group broadcast dispatch with observer-session isolation, cross-account dedupe safeguards, and non-mention history buffering rules that avoid duplicate replay in broadcast/topic workflows. (#29575) Thanks @ohmyskyhigh.

View File

@@ -1288,6 +1288,7 @@ export async function handleFeishuMessage(params: {
CommandAuthorized: commandAuthorized,
OriginatingChannel: "feishu" as const,
OriginatingTo: feishuTo,
GroupSystemPrompt: isGroup ? groupConfig?.systemPrompt?.trim() || undefined : undefined,
...mediaPayload,
});

View File

@@ -10,7 +10,7 @@ import { recordChannelActivity } from "../infra/channel-activity.js";
import { resolveAgentRoute } from "../routing/resolve-route.js";
import { resolvePinnedMainDmOwnerFromAllowlist } from "../security/dm-policy-shared.js";
import { normalizeAllowFrom } from "./bot-access.js";
import type { ResolvedLineAccount } from "./types.js";
import type { ResolvedLineAccount, LineGroupConfig } from "./types.js";
interface MediaRef {
path: string;
@@ -206,6 +206,20 @@ function resolveLineAddresses(params: {
return { fromAddress, toAddress, originatingTo };
}
function resolveLineGroupSystemPrompt(
groups: Record<string, LineGroupConfig | undefined> | undefined,
source: LineSourceInfoWithPeerId,
): string | undefined {
if (!groups) {
return undefined;
}
const entry =
(source.groupId ? (groups[source.groupId] ?? groups[`group:${source.groupId}`]) : undefined) ??
(source.roomId ? (groups[source.roomId] ?? groups[`room:${source.roomId}`]) : undefined) ??
groups["*"];
return entry?.systemPrompt?.trim() || undefined;
}
async function finalizeLineInboundContext(params: {
cfg: OpenClawConfig;
account: ResolvedLineAccount;
@@ -288,6 +302,9 @@ async function finalizeLineInboundContext(params: {
...params.locationContext,
OriginatingChannel: "line" as const,
OriginatingTo: originatingTo,
GroupSystemPrompt: params.source.isGroup
? resolveLineGroupSystemPrompt(params.account.config.groups, params.source)
: undefined,
});
const pinnedMainDmOwner = !params.source.isGroup