mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-26 02:04:37 +08:00
fix(ai): ensure builtin masking rules before preprocessing
This commit is contained in:
1 parent
cd9f297124
commit
f4580c55f1
3 files changed
+105
-24
No files matched your search
+8
-24
@@ -17,6 +17,7 @@ import { useSkillStore } from '@/stores/skill'
|
||||
import { useLLMStore } from '@/stores/llm'
|
||||
import type { TokenUsage, AgentRuntimeStatus, SerializedErrorInfo } from '@electron/shared/types'
|
||||
import { useAgentStreamService } from '@/services/ai-stream/service'
|
||||
import { buildSerializablePreprocessConfig, shouldEnsureDesensitizeRulesBeforeSerialize } from './aiPreprocessConfig'
|
||||
|
||||
// 工具调用记录
|
||||
export interface ToolCallRecord {
|
||||
@@ -811,7 +812,7 @@ export const useAIChatStore = defineStore('aiChatRuntime', () => {
|
||||
? { platformId: state.ownerInfo.platformId, displayName: state.ownerInfo.displayName }
|
||||
: undefined,
|
||||
mentionedMembers: currentMentionedMembers.length > 0 ? currentMentionedMembers : undefined,
|
||||
preprocessConfig: buildSerializablePreprocessConfig(),
|
||||
preprocessConfig: await buildReadySerializablePreprocessConfig(),
|
||||
searchContextBefore: aiGlobalSettings.value.searchContextBefore,
|
||||
searchContextAfter: aiGlobalSettings.value.searchContextAfter,
|
||||
}
|
||||
@@ -1096,30 +1097,13 @@ export const useAIChatStore = defineStore('aiChatRuntime', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function buildSerializablePreprocessConfig() {
|
||||
async function buildReadySerializablePreprocessConfig() {
|
||||
const preprocessConfig = settingsStore.aiPreprocessConfig
|
||||
const hasPreprocess =
|
||||
preprocessConfig.dataCleaning ||
|
||||
preprocessConfig.mergeConsecutive ||
|
||||
preprocessConfig.blacklistKeywords.length > 0 ||
|
||||
preprocessConfig.denoise ||
|
||||
preprocessConfig.desensitize ||
|
||||
preprocessConfig.anonymizeNames
|
||||
|
||||
if (!hasPreprocess) return undefined
|
||||
return {
|
||||
dataCleaning: preprocessConfig.dataCleaning,
|
||||
mergeConsecutive: preprocessConfig.mergeConsecutive,
|
||||
mergeWindowSeconds: preprocessConfig.mergeWindowSeconds,
|
||||
blacklistKeywords: [...preprocessConfig.blacklistKeywords],
|
||||
denoise: preprocessConfig.denoise,
|
||||
desensitize: preprocessConfig.desensitize,
|
||||
desensitizeRules: preprocessConfig.desensitizeRules.map((rule) => ({
|
||||
...rule,
|
||||
locales: [...rule.locales],
|
||||
})),
|
||||
anonymizeNames: preprocessConfig.anonymizeNames,
|
||||
if (shouldEnsureDesensitizeRulesBeforeSerialize(preprocessConfig)) {
|
||||
await settingsStore.ensureDesensitizeRules()
|
||||
}
|
||||
|
||||
return buildSerializablePreprocessConfig(settingsStore.aiPreprocessConfig)
|
||||
}
|
||||
|
||||
function normalizeMentionLookupText(value: string): string {
|
||||
@@ -1360,7 +1344,7 @@ export const useAIChatStore = defineStore('aiChatRuntime', () => {
|
||||
? { platformId: state.ownerInfo.platformId, displayName: state.ownerInfo.displayName }
|
||||
: undefined,
|
||||
mentionedMembers: currentMentionedMembers.length > 0 ? currentMentionedMembers : undefined,
|
||||
preprocessConfig: buildSerializablePreprocessConfig(),
|
||||
preprocessConfig: await buildReadySerializablePreprocessConfig(),
|
||||
searchContextBefore: aiGlobalSettings.value.searchContextBefore,
|
||||
searchContextAfter: aiGlobalSettings.value.searchContextAfter,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { describe, it } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { shouldEnsureDesensitizeRulesBeforeSerialize } from './aiPreprocessConfig'
|
||||
|
||||
describe('AI preprocess config serialization guards', () => {
|
||||
it('requires built-in rules before serializing an enabled empty desensitize config', () => {
|
||||
assert.equal(
|
||||
shouldEnsureDesensitizeRulesBeforeSerialize({
|
||||
desensitize: true,
|
||||
desensitizeRules: [],
|
||||
}),
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('requires built-in rules before serializing enabled custom-only desensitize rules', () => {
|
||||
assert.equal(
|
||||
shouldEnsureDesensitizeRulesBeforeSerialize({
|
||||
desensitize: true,
|
||||
desensitizeRules: [
|
||||
{
|
||||
id: 'custom_staff_id',
|
||||
label: 'Staff ID',
|
||||
pattern: 'EMP-\\d+',
|
||||
replacement: '[Staff ID]',
|
||||
enabled: true,
|
||||
builtin: false,
|
||||
locales: [],
|
||||
},
|
||||
],
|
||||
}),
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('does not require built-in rules when enabled rules already include a built-in rule', () => {
|
||||
assert.equal(
|
||||
shouldEnsureDesensitizeRulesBeforeSerialize({
|
||||
desensitize: true,
|
||||
desensitizeRules: [
|
||||
{
|
||||
id: 'email',
|
||||
label: 'desensitize.rules.email',
|
||||
pattern: '[^@\\s]+@[^@\\s]+',
|
||||
replacement: '[Email]',
|
||||
enabled: true,
|
||||
builtin: true,
|
||||
locales: [],
|
||||
},
|
||||
],
|
||||
}),
|
||||
false
|
||||
)
|
||||
})
|
||||
|
||||
it('does not require built-in rules when masking is disabled', () => {
|
||||
assert.equal(
|
||||
shouldEnsureDesensitizeRulesBeforeSerialize({
|
||||
desensitize: false,
|
||||
desensitizeRules: [],
|
||||
}),
|
||||
false
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { PreprocessConfig } from '@electron/preload/index'
|
||||
|
||||
export function shouldEnsureDesensitizeRulesBeforeSerialize(
|
||||
config: Pick<PreprocessConfig, 'desensitize' | 'desensitizeRules'>
|
||||
): boolean {
|
||||
return config.desensitize && !config.desensitizeRules.some((rule) => rule.builtin)
|
||||
}
|
||||
|
||||
export function buildSerializablePreprocessConfig(config: PreprocessConfig) {
|
||||
const hasPreprocess =
|
||||
config.dataCleaning ||
|
||||
config.mergeConsecutive ||
|
||||
config.blacklistKeywords.length > 0 ||
|
||||
config.denoise ||
|
||||
config.desensitize ||
|
||||
config.anonymizeNames
|
||||
|
||||
if (!hasPreprocess) return undefined
|
||||
return {
|
||||
dataCleaning: config.dataCleaning,
|
||||
mergeConsecutive: config.mergeConsecutive,
|
||||
mergeWindowSeconds: config.mergeWindowSeconds,
|
||||
blacklistKeywords: [...config.blacklistKeywords],
|
||||
denoise: config.denoise,
|
||||
desensitize: config.desensitize,
|
||||
desensitizeRules: config.desensitizeRules.map((rule) => ({
|
||||
...rule,
|
||||
locales: [...rule.locales],
|
||||
})),
|
||||
anonymizeNames: config.anonymizeNames,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user