feat: 知识库更新,优化批量语音转写 - 合并索引 - 增加会话级批量转写处理 - 补充语音转写回归测试

This commit is contained in:
电摇小子
2026-08-06 20:31:08 +08:00
parent a0e8ab278f
commit 0ec2e6a0be
34 changed files with 2589 additions and 53 deletions
+7 -1
View File
@@ -1,4 +1,8 @@
import type { KnowledgeEvidence, KnowledgeSearchIpcResult } from './knowledge'
import type {
KnowledgeEvidence,
KnowledgeSearchIpcResult,
KnowledgeVoiceCoverage
} from './knowledge'
export type AiSearchScope = 'global' | 'groups' | 'contacts' | 'conversation'
export type AiSearchRange = 'today' | '7d' | '30d' | 'all'
@@ -210,6 +214,7 @@ export interface AiSearchRetrievalContract {
fallbackUsed: boolean
fallbackReason?: string
suspicious: boolean
voiceCoverage?: KnowledgeVoiceCoverage
}
export interface AiSearchPipelineResult {
@@ -224,6 +229,7 @@ export interface AiSearchPipelineResult {
| 'indexedMessageCount'
| 'indexedChunkCount'
| 'totalMessages'
| 'voiceCoverage'
>
candidateEvidenceCount: number
retrieval: AiSearchRetrievalContract
+12
View File
@@ -40,6 +40,8 @@ export interface KnowledgeSourceMessage {
text?: string
attachment?: KnowledgeAttachmentMetadata
voiceTranscript?: string
/** Local coverage state only. Error text is never copied into the index. */
voiceTranscriptState?: 'pending' | 'transcribed' | 'failed'
}
export interface KnowledgeNormalizedMessage extends KnowledgeSourceMessage {
@@ -171,10 +173,19 @@ export interface KnowledgeEvidence {
/** Unix epoch milliseconds. */
timestamp: number
messageIds: string[]
/** The source type belongs to the original message, not the retrieval method. */
sourceKind: KnowledgeMessageKind
text: string
score?: number
}
export interface KnowledgeVoiceCoverage {
voiceMessageCount: number
transcribedVoiceCount: number
failedVoiceCount: number
voiceCoverageComplete: boolean
}
/** A bounded, local summary of a single conversation retrieval. */
export interface KnowledgeConversationRetrieval {
conversationId: string
@@ -255,6 +266,7 @@ export interface KnowledgeSearchResult {
indexedChunkCount: number
timings: KnowledgeSearchTimings
conversationRetrieval?: KnowledgeConversationRetrieval
voiceCoverage?: KnowledgeVoiceCoverage
}
/** Renderer-facing request. Chat timestamps use Unix seconds in the existing UI. */
+70
View File
@@ -7,6 +7,27 @@ export interface VoiceMessageReference {
svrId?: string | number
}
export type VoiceRecognitionPriority = 'interactive' | 'background'
export type VoiceTranscriptState = 'pending' | 'transcribed' | 'failed'
export interface VoiceTranscriptUpdate {
accountIdentity: string
reference: VoiceMessageReference
messageIdentity: string
state: Exclude<VoiceTranscriptState, 'pending'>
transcript?: string
error?: string
cached: boolean
}
export interface VoiceTranscriptSnapshot {
state: VoiceTranscriptState
transcript?: string
error?: string
updatedAt?: number
}
export type VoiceModelState =
| 'missing'
| 'downloading'
@@ -55,4 +76,53 @@ export interface VoiceRecognitionResult {
code?: VoiceRecognitionErrorCode
}
export type VoiceBatchRange = 'recent_30_days' | 'current_year' | 'selected_history'
export interface VoiceBatchRequest {
conversationIds: string[]
range: VoiceBatchRange
}
export interface VoiceBatchPreflight {
accountIdentity: string
conversationCount: number
voiceMessageCount: number
cachedCount: number
pendingCount: number
failedCount: number
estimatedDurationMs: number | null
modelReady: boolean
}
/**
* Lightweight per-conversation counts for the batch-selection UI. Unlike a
* preflight this deliberately does not enumerate every voice message.
*/
export interface VoiceBatchConversationSummary {
conversationId: string
voiceMessageCount: number | null
}
export type VoiceBatchState =
| 'idle'
| 'pending'
| 'processing'
| 'completed'
| 'partially_failed'
| 'cancelled'
export interface VoiceBatchProgress {
accountIdentity: string
state: VoiceBatchState
total: number
processed: number
cached: number
succeeded: number
failed: number
currentConversationId?: string
currentMessageIdentity?: string
elapsedMs: number
estimatedRemainingMs: number | null
}
export interface VoiceModelProgressEvent extends VoiceModelStatus {}