test: 暂存代码

This commit is contained in:
电摇小子
2026-08-06 20:29:25 +08:00
parent 307d247660
commit ad4b3a8074
43 changed files with 9978 additions and 512 deletions
+158
View File
@@ -0,0 +1,158 @@
import type { KnowledgeConversationInput, KnowledgeSourceMessage } from '../../src/shared/knowledge'
export type KnowledgeBenchmarkCategory = 'fact' | 'person' | 'time' | 'decision' | 'semantic'
export interface KnowledgeBenchmarkCase {
id: string
category: KnowledgeBenchmarkCategory
question: string
oldSearchTerms: string[]
expectedMessageIds: string[]
}
export const FIXTURE_ACCOUNT_A = 'fixture-account-alpha'
export const FIXTURE_ACCOUNT_B = 'fixture-account-beta'
function message(
id: string,
conversationId: string,
createTime: number,
text: string,
extra: Partial<KnowledgeSourceMessage> = {}
): KnowledgeSourceMessage {
return {
accountId: extra.accountId || FIXTURE_ACCOUNT_A,
conversationId,
messageId: id,
createTime,
senderId: extra.senderId || 'fixture-sender',
senderName: extra.senderName || '脱敏成员',
kind: extra.kind || 'text',
text,
attachment: extra.attachment,
voiceTranscript: extra.voiceTranscript
}
}
/** Deterministic and fully synthetic: no wxid, file path, secret, or real chat text. */
export function createKnowledgeBenchmarkFixture(): {
conversations: KnowledgeConversationInput[]
cases: KnowledgeBenchmarkCase[]
} {
const messages: KnowledgeSourceMessage[] = []
const cases: KnowledgeBenchmarkCase[] = []
const base = Date.UTC(2025, 0, 1)
const add = (
category: KnowledgeBenchmarkCategory,
index: number,
text: string,
question: string,
oldSearchTerms: string[],
extra: Partial<KnowledgeSourceMessage> = {}
): void => {
const conversationId = `fixture-${category}-${index % 5}`
const id = `fixture-${category}-${index}-evidence`
messages.push(message(id, conversationId, base + (cases.length + 1) * 60_000, text, extra))
messages.push(
message(
`fixture-${category}-${index}-context`,
conversationId,
base + (cases.length + 1) * 60_000 + 20_000,
`脱敏上下文 ${index}:确认后续会回到原始消息核对。`,
{ senderId: 'fixture-context', senderName: '脱敏同事' }
)
)
cases.push({
id: `question-${category}-${index}`,
category,
question,
oldSearchTerms,
expectedMessageIds: [id]
})
}
for (let index = 1; index <= 20; index += 1) {
add(
'fact',
index,
`资料编号 FACT-${index} 的部署地址是 https://example.invalid/fact-${index},附件名称是 runbook-${index}.pdf。`,
`${index} 项部署资料在哪里?`,
[`FACT-${index}`, `runbook-${index}.pdf`],
{ attachment: { name: `runbook-${index}.pdf`, kind: 'file' } }
)
add(
'person',
index,
`成员 代号成员${index} 负责发布检查,并说明本周会完成验证清单。`,
`代号成员${index} 最近负责什么?`,
[`代号成员${index}`, '发布检查']
)
add(
'time',
index,
`日期标记 TIME-${index}:在第 ${index} 次周会讨论了回归安排和验收顺序。`,
`TIME-${index} 当天讨论了什么?`,
[`TIME-${index}`, '回归安排']
)
add(
'decision',
index,
`决策 DECISION-${index}:最终选择方案蓝图${index},原因是可追溯、可回滚且维护成本更低。`,
`为什么第 ${index} 个决策选择方案蓝图${index}`,
[`DECISION-${index}`, `方案蓝图${index}`]
)
add(
'semantic',
index,
`语义样本 ${index}:把分散的讨论归档,方便以后重新查看和核对当时的上下文。`,
`哪里提到把内容收起来以后查看?第 ${index} 条。`,
[`内容收起来${index}`],
{ kind: 'voice', voiceTranscript: `请将分散讨论集中保存,便于之后重新查看,第 ${index} 条。` }
)
}
const grouped = new Map<string, KnowledgeSourceMessage[]>()
for (const item of messages) {
const current = grouped.get(item.conversationId) || []
current.push(item)
grouped.set(item.conversationId, current)
}
return {
conversations: Array.from(grouped.entries()).map(([conversationId, source]) => ({
conversationId,
completeSnapshot: true,
messages: source
})),
cases
}
}
export function createSyntheticConversation(
accountId: string,
conversationId: string,
startIndex: number,
count: number,
distribution: 'short' | 'mixed' | 'long'
): KnowledgeConversationInput {
const base = Date.UTC(2025, 0, 1) + startIndex * 1000
const messages: KnowledgeSourceMessage[] = []
const shortText = '脱敏短消息:已确认。'
const mixedText = '脱敏普通消息:讨论本地知识库、索引状态、证据回跳和增量恢复。'
const longText = `脱敏长文本/语音转写:${'用于容量测试的可检索上下文。'.repeat(12)}`
for (let offset = 0; offset < count; offset += 1) {
const index = startIndex + offset
const text = distribution === 'short' ? shortText : distribution === 'mixed' ? mixedText : longText
messages.push({
accountId,
conversationId,
messageId: `synthetic-${distribution}-${index}`,
createTime: base + offset * 60_000,
senderId: `fixture-member-${index % 8}`,
senderName: `脱敏成员${index % 8}`,
kind: distribution === 'long' && index % 4 === 0 ? 'voice' : 'text',
text,
voiceTranscript: distribution === 'long' && index % 4 === 0 ? longText : undefined,
attachment:
index % 97 === 0 ? { name: `fixture-${index}.txt`, kind: 'file', sizeBytes: 2048 } : undefined
})
}
return { conversationId, completeSnapshot: true, messages }
}