plugin-sensitive-filter-xr 0.1.8 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  - `beforeAgent`: evaluates and optionally rewrites/blocks input
11
11
  - `wrapModelCall`: evaluates and optionally rewrites/blocks output
12
- - `afterAgent`: writes audit snapshot
12
+ - `afterAgent`: sends matched alerts to configured WeCom group webhooks
13
13
 
14
14
  ## Configuration
15
15
 
@@ -22,6 +22,17 @@
22
22
  | `caseSensitive` | `boolean` | No | `false` | Case-sensitive matching in `rule` mode. |
23
23
  | `normalize` | `boolean` | No | `true` | Whitespace normalization in `rule` mode. |
24
24
  | `llm` | `object` | Runtime-required in `llm` mode | - | LLM mode configuration. |
25
+ | `wecom` | `object` | No | disabled when no groups | WeCom webhook notification config. |
26
+
27
+ ### WeCom Notify (`wecom`)
28
+
29
+ | Field | Type | Required | Default | Description |
30
+ | --- | --- | --- | --- | --- |
31
+ | `enabled` | `boolean` | No | `true` | Turn notification on/off. |
32
+ | `groups` | `Array<{name?, webhookUrl}>` | Runtime-required for sending | `[]` | One or more WeCom group webhook targets. |
33
+ | `mentionedList` | `string[]` | No | `[]` | Optional `@member` list. |
34
+ | `mentionedMobileList` | `string[]` | No | `[]` | Optional `@mobile` list. |
35
+ | `timeoutMs` | `number` | No | `10000` | Per webhook request timeout (max `120000`). |
25
36
 
26
37
  ### Rule Mode (`mode=rule`)
27
38
 
@@ -55,6 +66,7 @@ Notes:
55
66
  - The middleware internally enforces rewrite-only behavior for LLM hits.
56
67
  - Structured output method is internally adaptive; the UI does not expose method selection.
57
68
  - Internal decision traces are muted from chat output.
69
+ - Notifications are sent only when there is at least one matched record.
58
70
 
59
71
  ## Backward Compatibility
60
72
 
@@ -90,8 +102,6 @@ Current behavior:
90
102
  - Ensure `model/scope/rulePrompt` are all present.
91
103
 
92
104
  3. Unexpected rewrites in LLM mode:
93
- - Check audit records for `source=error-policy` and `reason` starting with `llm-error:`.
105
+ - Check runtime logs for entries with `source=error-policy` and `reason` starting with `llm-error:`.
94
106
 
95
107
  ## Validation Commands
96
-
97
-
@@ -1 +1 @@
1
- {"version":3,"file":"sensitiveFilter.d.ts","sourceRoot":"","sources":["../../src/lib/sensitiveFilter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAa,oBAAoB,EAA8B,MAAM,kBAAkB,CAAA;AAGnG,OAAO,EACL,eAAe,EAGf,uBAAuB,EACvB,wBAAwB,EAEzB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAML,qBAAqB,EAKtB,MAAM,YAAY,CAAA;AAoxBnB,qBAEa,yBAA0B,YAAW,wBAAwB,CAAC,qBAAqB,CAAC;IAE/F,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IAEvC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CA6NlC;IAEK,gBAAgB,CACpB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,eAAe,CAAC;IAa3B,OAAO,CAAC,wBAAwB;IAgThC,OAAO,CAAC,uBAAuB;CA2fhC;AAED,YAAY,EAAE,qBAAqB,EAAE,CAAA"}
1
+ {"version":3,"file":"sensitiveFilter.d.ts","sourceRoot":"","sources":["../../src/lib/sensitiveFilter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAa,oBAAoB,EAA8B,MAAM,kBAAkB,CAAA;AAGnG,OAAO,EACL,eAAe,EAGf,uBAAuB,EACvB,wBAAwB,EAEzB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAML,qBAAqB,EAMtB,MAAM,YAAY,CAAA;AA26BnB,qBAEa,yBAA0B,YAAW,wBAAwB,CAAC,qBAAqB,CAAC;IAE/F,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IAEvC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAqRlC;IAEK,gBAAgB,CACpB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,eAAe,CAAC;IAa3B,OAAO,CAAC,wBAAwB;IA8ThC,OAAO,CAAC,uBAAuB;CA2gBhC;AAED,YAAY,EAAE,qBAAqB,EAAE,CAAA"}
@@ -11,6 +11,7 @@ const SENSITIVE_FILTER_MIDDLEWARE_NAME = 'SensitiveFilterMiddleware';
11
11
  const DEFAULT_INPUT_BLOCK_MESSAGE = '输入内容触发敏感策略,已拦截。';
12
12
  const DEFAULT_OUTPUT_BLOCK_MESSAGE = '输出内容触发敏感策略,已拦截。';
13
13
  const DEFAULT_REWRITE_TEXT = '[已过滤]';
14
+ const DEFAULT_WECOM_TIMEOUT_MS = 10000;
14
15
  const CONFIG_PARSE_ERROR = '敏感词过滤配置格式不正确,请检查填写内容。';
15
16
  const BUSINESS_RULES_VALIDATION_ERROR = '请至少配置 1 条有效业务规则(pattern/type/action/scope/severity)。';
16
17
  const LLM_MODE_VALIDATION_ERROR = '请完善 LLM 过滤配置:需填写过滤模型、生效范围、审核规则说明。';
@@ -32,6 +33,51 @@ function toNonEmptyString(value) {
32
33
  const trimmed = value.trim();
33
34
  return trimmed ? trimmed : null;
34
35
  }
36
+ function normalizeStringList(value) {
37
+ if (!Array.isArray(value)) {
38
+ return [];
39
+ }
40
+ const unique = new Set();
41
+ for (const item of value) {
42
+ const normalized = toNonEmptyString(item);
43
+ if (normalized) {
44
+ unique.add(normalized);
45
+ }
46
+ }
47
+ return [...unique];
48
+ }
49
+ function resolveRuntimeWecomConfig(config) {
50
+ if (!isRecord(config) || config.enabled === false) {
51
+ return null;
52
+ }
53
+ const groups = [];
54
+ const drafts = Array.isArray(config.groups) ? config.groups : [];
55
+ for (const item of drafts) {
56
+ if (!isRecord(item)) {
57
+ continue;
58
+ }
59
+ const webhookUrl = toNonEmptyString(item.webhookUrl);
60
+ if (!webhookUrl) {
61
+ continue;
62
+ }
63
+ groups.push({
64
+ name: toNonEmptyString(item.name) ?? undefined,
65
+ webhookUrl,
66
+ });
67
+ }
68
+ if (groups.length === 0) {
69
+ return null;
70
+ }
71
+ const timeoutMs = typeof config.timeoutMs === 'number' && Number.isFinite(config.timeoutMs) && config.timeoutMs > 0
72
+ ? Math.min(Math.floor(config.timeoutMs), 120000)
73
+ : DEFAULT_WECOM_TIMEOUT_MS;
74
+ return {
75
+ groups,
76
+ timeoutMs,
77
+ mentionedList: normalizeStringList(config.mentionedList),
78
+ mentionedMobileList: normalizeStringList(config.mentionedMobileList),
79
+ };
80
+ }
35
81
  function buildInternalModelConfig(model) {
36
82
  const options = isRecord(model.options) ? model.options : {};
37
83
  return {
@@ -87,6 +133,26 @@ function extractInputText(state, runtime) {
87
133
  }
88
134
  return '';
89
135
  }
136
+ function buildMatchedNotificationMessage(input) {
137
+ const matched = input.records.filter((entry) => entry.matched);
138
+ const lines = [
139
+ '[敏感内容命中告警]',
140
+ `节点: ${input.nodeTitle || SENSITIVE_FILTER_MIDDLEWARE_NAME}`,
141
+ `模式: ${input.mode}`,
142
+ `最终动作: ${input.finalAction}`,
143
+ `命中数量: ${matched.length}`,
144
+ ];
145
+ if (input.runtimeConfigurable?.thread_id) {
146
+ lines.push(`threadId: ${input.runtimeConfigurable.thread_id}`);
147
+ }
148
+ if (input.runtimeConfigurable?.executionId) {
149
+ lines.push(`executionId: ${input.runtimeConfigurable.executionId}`);
150
+ }
151
+ matched.forEach((entry, index) => {
152
+ lines.push(`${index + 1}. phase=${entry.phase}, source=${entry.source}, action=${entry.action ?? 'n/a'}, reason=${entry.reason ?? 'n/a'}`);
153
+ });
154
+ return lines.join('\n');
155
+ }
90
156
  function getSeverityWeight(severity) {
91
157
  return severity === 'high' ? 2 : 1;
92
158
  }
@@ -538,6 +604,45 @@ function withTimeout(promise, timeoutMs) {
538
604
  });
539
605
  });
540
606
  }
607
+ async function dispatchWecomNotification(wecomConfig, message) {
608
+ if (!wecomConfig || !message.trim()) {
609
+ return;
610
+ }
611
+ const payload = {
612
+ msgtype: 'text',
613
+ text: {
614
+ content: message,
615
+ mentioned_list: wecomConfig.mentionedList,
616
+ mentioned_mobile_list: wecomConfig.mentionedMobileList,
617
+ },
618
+ };
619
+ for (const group of wecomConfig.groups) {
620
+ try {
621
+ const response = await withTimeout(fetch(group.webhookUrl, {
622
+ method: 'POST',
623
+ headers: {
624
+ 'Content-Type': 'application/json',
625
+ },
626
+ body: JSON.stringify(payload),
627
+ }), wecomConfig.timeoutMs);
628
+ if (!response.ok) {
629
+ throw new Error(`HTTP ${response.status}`);
630
+ }
631
+ const body = await response.json().catch(() => null);
632
+ const rawErrCode = isRecord(body) ? body['errcode'] : undefined;
633
+ const errCode = typeof rawErrCode === 'number' ? rawErrCode : Number(rawErrCode);
634
+ if (!Number.isFinite(errCode) || errCode !== 0) {
635
+ const errMsg = isRecord(body) ? String(body['errmsg'] ?? '') : 'unknown';
636
+ throw new Error(`errcode=${String(rawErrCode ?? 'unknown')}, errmsg=${errMsg}`);
637
+ }
638
+ }
639
+ catch (error) {
640
+ const target = group.name ? `${group.name}(${group.webhookUrl})` : group.webhookUrl;
641
+ // Notify failure should not break model execution.
642
+ console.warn(`[${SENSITIVE_FILTER_MIDDLEWARE_NAME}] Failed to send WeCom notification to ${target}: ${getErrorText(error)}`);
643
+ }
644
+ }
645
+ }
541
646
  function normalizeConfigurable(input) {
542
647
  if (!isRecord(input)) {
543
648
  return null;
@@ -797,6 +902,62 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
797
902
  },
798
903
  required: ['model', 'scope', 'rulePrompt'],
799
904
  },
905
+ wecom: {
906
+ type: 'object',
907
+ 'x-ui': {
908
+ span: 2,
909
+ },
910
+ title: {
911
+ en_US: 'WeCom Notify',
912
+ zh_Hans: '企业微信群通知',
913
+ },
914
+ description: {
915
+ en_US: 'When sensitive content is matched, send alerts to configured WeCom group webhooks.',
916
+ zh_Hans: '敏感内容命中后,发送告警到已配置的企业微信群 webhook。',
917
+ },
918
+ properties: {
919
+ enabled: {
920
+ type: 'boolean',
921
+ default: true,
922
+ title: { en_US: 'Enabled', zh_Hans: '启用通知' },
923
+ },
924
+ timeoutMs: {
925
+ type: 'number',
926
+ title: { en_US: 'Timeout (ms)', zh_Hans: '请求超时(毫秒)' },
927
+ },
928
+ mentionedList: {
929
+ type: 'array',
930
+ title: { en_US: 'Mentioned List', zh_Hans: '@成员列表' },
931
+ items: {
932
+ type: 'string',
933
+ },
934
+ },
935
+ mentionedMobileList: {
936
+ type: 'array',
937
+ title: { en_US: 'Mentioned Mobile List', zh_Hans: '@手机号列表' },
938
+ items: {
939
+ type: 'string',
940
+ },
941
+ },
942
+ groups: {
943
+ type: 'array',
944
+ title: { en_US: 'Group Webhooks', zh_Hans: '群聊 Webhook 配置' },
945
+ items: {
946
+ type: 'object',
947
+ properties: {
948
+ name: {
949
+ type: 'string',
950
+ title: { en_US: 'Group Name', zh_Hans: '群名称(可选)' },
951
+ },
952
+ webhookUrl: {
953
+ type: 'string',
954
+ title: { en_US: 'Webhook URL', zh_Hans: 'Webhook 地址' },
955
+ },
956
+ },
957
+ },
958
+ },
959
+ },
960
+ },
800
961
  },
801
962
  required: ['mode'],
802
963
  allOf: [
@@ -829,6 +990,7 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
829
990
  createRuleModeMiddleware(config, context) {
830
991
  const caseSensitive = config.caseSensitive ?? false;
831
992
  const normalize = config.normalize ?? true;
993
+ const wecomConfig = resolveRuntimeWecomConfig(config.wecom);
832
994
  const customRules = normalizeRuleDrafts(config.rules ?? []);
833
995
  const allRules = [...customRules];
834
996
  const hasEffectiveRules = allRules.length > 0;
@@ -1080,13 +1242,26 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
1080
1242
  return replaceModelResponseText(response, rewrittenOutput);
1081
1243
  },
1082
1244
  afterAgent: async () => {
1083
- await persistAuditSnapshot();
1245
+ const matchedRecords = auditEntries.filter((entry) => entry.matched);
1246
+ if (matchedRecords.length > 0) {
1247
+ const notification = buildMatchedNotificationMessage({
1248
+ mode: 'rule',
1249
+ nodeTitle: context.node.title ?? SENSITIVE_FILTER_MIDDLEWARE_NAME,
1250
+ finalAction,
1251
+ records: matchedRecords,
1252
+ runtimeConfigurable,
1253
+ });
1254
+ await dispatchWecomNotification(wecomConfig, notification);
1255
+ }
1256
+ // Keep audit persistence implementation for future fallback.
1257
+ // await persistAuditSnapshot()
1084
1258
  return undefined;
1085
1259
  },
1086
1260
  };
1087
1261
  }
1088
1262
  createLlmModeMiddleware(config, context) {
1089
1263
  const llmDraftConfig = config.llm;
1264
+ const wecomConfig = resolveRuntimeWecomConfig(config.wecom);
1090
1265
  let resolvedLlmConfig = null;
1091
1266
  let modelPromise = null;
1092
1267
  const structuredModelPromises = new Map();
@@ -1100,7 +1275,9 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
1100
1275
  const llmConfig = getLlmConfig();
1101
1276
  if (!modelPromise) {
1102
1277
  modelPromise = this.commandBus.execute(new CreateModelClientCommand(buildInternalModelConfig(llmConfig.model), {
1103
- usageCallback: () => { },
1278
+ usageCallback: () => {
1279
+ //
1280
+ },
1104
1281
  }));
1105
1282
  }
1106
1283
  return modelPromise;
@@ -1496,7 +1673,19 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
1496
1673
  return replaceModelResponseText(response, toNonEmptyString(decision.replacementText) ?? llmConfig.rewriteFallbackText);
1497
1674
  },
1498
1675
  afterAgent: async () => {
1499
- await persistAuditSnapshot();
1676
+ const matchedRecords = auditEntries.filter((entry) => entry.matched);
1677
+ if (matchedRecords.length > 0) {
1678
+ const notification = buildMatchedNotificationMessage({
1679
+ mode: 'llm',
1680
+ nodeTitle: context.node.title ?? SENSITIVE_FILTER_MIDDLEWARE_NAME,
1681
+ finalAction,
1682
+ records: matchedRecords,
1683
+ runtimeConfigurable,
1684
+ });
1685
+ await dispatchWecomNotification(wecomConfig, notification);
1686
+ }
1687
+ // Keep audit persistence implementation for future fallback.
1688
+ // await persistAuditSnapshot()
1500
1689
  return undefined;
1501
1690
  },
1502
1691
  };
@@ -14,6 +14,7 @@ export type RuleModeConfig = {
14
14
  rules?: Array<Partial<SensitiveRule> | null>;
15
15
  caseSensitive?: boolean;
16
16
  normalize?: boolean;
17
+ wecom?: WecomNotifyConfig | null;
17
18
  generalPack?: unknown;
18
19
  };
19
20
  export type LlmScope = 'input' | 'output' | 'both';
@@ -34,9 +35,21 @@ export type LlmFilterConfig = {
34
35
  export type LlmModeConfig = {
35
36
  mode: 'llm';
36
37
  llm?: LlmFilterConfig | null;
38
+ wecom?: WecomNotifyConfig | null;
37
39
  generalPack?: unknown;
38
40
  };
39
41
  export type SensitiveFilterConfig = RuleModeConfig | LlmModeConfig;
42
+ export type WecomNotifyGroup = {
43
+ name?: string | null;
44
+ webhookUrl?: string | null;
45
+ };
46
+ export type WecomNotifyConfig = {
47
+ enabled?: boolean;
48
+ groups?: Array<WecomNotifyGroup | null>;
49
+ mentionedList?: string[] | null;
50
+ mentionedMobileList?: string[] | null;
51
+ timeoutMs?: number | null;
52
+ };
40
53
  export type LlmDecision = {
41
54
  matched: boolean;
42
55
  action?: 'block' | 'rewrite';
@@ -80,9 +93,44 @@ export declare const sensitiveFilterConfigSchema: z.ZodUnion<[z.ZodObject<{
80
93
  }>>, "many">>>;
81
94
  caseSensitive: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
82
95
  normalize: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
96
+ wecom: z.ZodDefault<z.ZodNullable<z.ZodOptional<z.ZodObject<{
97
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
98
+ groups: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodNullable<z.ZodObject<{
99
+ name: z.ZodNullable<z.ZodOptional<z.ZodString>>;
100
+ webhookUrl: z.ZodNullable<z.ZodOptional<z.ZodString>>;
101
+ }, "strip", z.ZodTypeAny, {
102
+ name?: string;
103
+ webhookUrl?: string;
104
+ }, {
105
+ name?: string;
106
+ webhookUrl?: string;
107
+ }>>, "many">>>;
108
+ mentionedList: z.ZodDefault<z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>>;
109
+ mentionedMobileList: z.ZodDefault<z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>>;
110
+ timeoutMs: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
111
+ }, "strip", z.ZodTypeAny, {
112
+ timeoutMs?: number;
113
+ enabled?: boolean;
114
+ groups?: {
115
+ name?: string;
116
+ webhookUrl?: string;
117
+ }[];
118
+ mentionedList?: string[];
119
+ mentionedMobileList?: string[];
120
+ }, {
121
+ timeoutMs?: number;
122
+ enabled?: boolean;
123
+ groups?: {
124
+ name?: string;
125
+ webhookUrl?: string;
126
+ }[];
127
+ mentionedList?: string[];
128
+ mentionedMobileList?: string[];
129
+ }>>>>;
83
130
  llm: z.ZodOptional<z.ZodUnknown>;
84
131
  generalPack: z.ZodOptional<z.ZodUnknown>;
85
132
  }, "strip", z.ZodTypeAny, {
133
+ llm?: unknown;
86
134
  mode?: "rule";
87
135
  rules?: {
88
136
  id?: string;
@@ -95,9 +143,19 @@ export declare const sensitiveFilterConfigSchema: z.ZodUnion<[z.ZodObject<{
95
143
  }[];
96
144
  caseSensitive?: boolean;
97
145
  normalize?: boolean;
98
- llm?: unknown;
146
+ wecom?: {
147
+ timeoutMs?: number;
148
+ enabled?: boolean;
149
+ groups?: {
150
+ name?: string;
151
+ webhookUrl?: string;
152
+ }[];
153
+ mentionedList?: string[];
154
+ mentionedMobileList?: string[];
155
+ };
99
156
  generalPack?: unknown;
100
157
  }, {
158
+ llm?: unknown;
101
159
  mode?: "rule";
102
160
  rules?: {
103
161
  id?: string;
@@ -110,7 +168,16 @@ export declare const sensitiveFilterConfigSchema: z.ZodUnion<[z.ZodObject<{
110
168
  }[];
111
169
  caseSensitive?: boolean;
112
170
  normalize?: boolean;
113
- llm?: unknown;
171
+ wecom?: {
172
+ timeoutMs?: number;
173
+ enabled?: boolean;
174
+ groups?: {
175
+ name?: string;
176
+ webhookUrl?: string;
177
+ }[];
178
+ mentionedList?: string[];
179
+ mentionedMobileList?: string[];
180
+ };
114
181
  generalPack?: unknown;
115
182
  }>, z.ZodObject<{
116
183
  mode: z.ZodLiteral<"llm">;
@@ -148,15 +215,45 @@ export declare const sensitiveFilterConfigSchema: z.ZodUnion<[z.ZodObject<{
148
215
  rewriteFallbackText?: string;
149
216
  timeoutMs?: number;
150
217
  }>>>>;
218
+ wecom: z.ZodDefault<z.ZodNullable<z.ZodOptional<z.ZodObject<{
219
+ enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
220
+ groups: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodNullable<z.ZodObject<{
221
+ name: z.ZodNullable<z.ZodOptional<z.ZodString>>;
222
+ webhookUrl: z.ZodNullable<z.ZodOptional<z.ZodString>>;
223
+ }, "strip", z.ZodTypeAny, {
224
+ name?: string;
225
+ webhookUrl?: string;
226
+ }, {
227
+ name?: string;
228
+ webhookUrl?: string;
229
+ }>>, "many">>>;
230
+ mentionedList: z.ZodDefault<z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>>;
231
+ mentionedMobileList: z.ZodDefault<z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>>;
232
+ timeoutMs: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
233
+ }, "strip", z.ZodTypeAny, {
234
+ timeoutMs?: number;
235
+ enabled?: boolean;
236
+ groups?: {
237
+ name?: string;
238
+ webhookUrl?: string;
239
+ }[];
240
+ mentionedList?: string[];
241
+ mentionedMobileList?: string[];
242
+ }, {
243
+ timeoutMs?: number;
244
+ enabled?: boolean;
245
+ groups?: {
246
+ name?: string;
247
+ webhookUrl?: string;
248
+ }[];
249
+ mentionedList?: string[];
250
+ mentionedMobileList?: string[];
251
+ }>>>>;
151
252
  rules: z.ZodOptional<z.ZodUnknown>;
152
253
  caseSensitive: z.ZodOptional<z.ZodUnknown>;
153
254
  normalize: z.ZodOptional<z.ZodUnknown>;
154
255
  generalPack: z.ZodOptional<z.ZodUnknown>;
155
256
  }, "strip", z.ZodTypeAny, {
156
- mode?: "llm";
157
- rules?: unknown;
158
- caseSensitive?: unknown;
159
- normalize?: unknown;
160
257
  llm?: {
161
258
  scope?: "input" | "output" | "both";
162
259
  model?: ICopilotModel;
@@ -169,12 +266,22 @@ export declare const sensitiveFilterConfigSchema: z.ZodUnion<[z.ZodObject<{
169
266
  rewriteFallbackText?: string;
170
267
  timeoutMs?: number;
171
268
  };
172
- generalPack?: unknown;
173
- }, {
174
269
  mode?: "llm";
175
270
  rules?: unknown;
176
271
  caseSensitive?: unknown;
177
272
  normalize?: unknown;
273
+ wecom?: {
274
+ timeoutMs?: number;
275
+ enabled?: boolean;
276
+ groups?: {
277
+ name?: string;
278
+ webhookUrl?: string;
279
+ }[];
280
+ mentionedList?: string[];
281
+ mentionedMobileList?: string[];
282
+ };
283
+ generalPack?: unknown;
284
+ }, {
178
285
  llm?: {
179
286
  scope?: "input" | "output" | "both";
180
287
  model?: ICopilotModel;
@@ -187,6 +294,20 @@ export declare const sensitiveFilterConfigSchema: z.ZodUnion<[z.ZodObject<{
187
294
  rewriteFallbackText?: string;
188
295
  timeoutMs?: number;
189
296
  };
297
+ mode?: "llm";
298
+ rules?: unknown;
299
+ caseSensitive?: unknown;
300
+ normalize?: unknown;
301
+ wecom?: {
302
+ timeoutMs?: number;
303
+ enabled?: boolean;
304
+ groups?: {
305
+ name?: string;
306
+ webhookUrl?: string;
307
+ }[];
308
+ mentionedList?: string[];
309
+ mentionedMobileList?: string[];
310
+ };
190
311
  generalPack?: unknown;
191
312
  }>]>;
192
313
  export declare const llmDecisionSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;IACzB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAA;IAC3B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAAA;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAClD,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,UAAU,GAAG,YAAY,CAAA;AAC3E,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,CAAA;AAEhD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,eAAe,CAAA;IAE9B,UAAU,CAAC,EAAE,cAAc,CAAA;IAE3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,KAAK,CAAA;IACX,GAAG,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IAE5B,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG,aAAa,CAAA;AAElE,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,mBAAmB,wSAA8R,CAAA;AAgD9T,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAuD,CAAA;AAE/F,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAM5B,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
package/dist/lib/types.js CHANGED
@@ -24,11 +24,25 @@ const llmConfigSchema = z
24
24
  rewriteFallbackText: z.string().optional().nullable(),
25
25
  timeoutMs: z.number().int().positive().max(120000).optional().nullable(),
26
26
  });
27
+ const wecomNotifyGroupSchema = z
28
+ .object({
29
+ name: z.string().optional().nullable(),
30
+ webhookUrl: z.string().optional().nullable(),
31
+ })
32
+ .nullable();
33
+ const wecomNotifyConfigSchema = z.object({
34
+ enabled: z.boolean().optional().default(true),
35
+ groups: z.array(wecomNotifyGroupSchema).optional().default([]),
36
+ mentionedList: z.array(z.string()).optional().nullable().default([]),
37
+ mentionedMobileList: z.array(z.string()).optional().nullable().default([]),
38
+ timeoutMs: z.number().int().positive().max(120000).optional().nullable(),
39
+ });
27
40
  const ruleModeConfigSchema = z.object({
28
41
  mode: z.literal('rule').optional(),
29
42
  rules: z.array(sensitiveRuleDraftSchema).optional().default([]),
30
43
  caseSensitive: z.boolean().optional().default(false),
31
44
  normalize: z.boolean().optional().default(true),
45
+ wecom: wecomNotifyConfigSchema.optional().nullable().default({}),
32
46
  llm: z.unknown().optional(),
33
47
  // Backward compatibility only.
34
48
  generalPack: z.unknown().optional(),
@@ -36,6 +50,7 @@ const ruleModeConfigSchema = z.object({
36
50
  const llmModeConfigSchema = z.object({
37
51
  mode: z.literal('llm'),
38
52
  llm: llmConfigSchema.optional().nullable().default({}),
53
+ wecom: wecomNotifyConfigSchema.optional().nullable().default({}),
39
54
  rules: z.unknown().optional(),
40
55
  caseSensitive: z.unknown().optional(),
41
56
  normalize: z.unknown().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plugin-sensitive-filter-xr",
3
- "version": "0.1.8",
3
+ "version": "0.1.20",
4
4
  "author": {
5
5
  "name": "XpertAI",
6
6
  "url": "https://xpertai.cn"