Enhancement: chat message document links (#12670)

This commit is contained in:
shamoon
2026-04-28 13:00:20 -07:00
committed by GitHub
parent 8e6fd010a0
commit 354df34e47
8 changed files with 274 additions and 18 deletions
+23 -1
View File
@@ -9,7 +9,11 @@ import {
} from '@angular/common/http/testing'
import { TestBed } from '@angular/core/testing'
import { environment } from 'src/environments/environment'
import { ChatService } from './chat.service'
import {
CHAT_METADATA_DELIMITER,
ChatService,
parseChatResponse,
} from './chat.service'
describe('ChatService', () => {
let service: ChatService
@@ -55,4 +59,22 @@ describe('ChatService', () => {
partialText: mockResponse,
} as any)
})
it('should parse chat references from the metadata trailer', () => {
const parsed = parseChatResponse(
`Answer text${CHAT_METADATA_DELIMITER}{"references":[{"id":1,"title":"Document 1"}]}`
)
expect(parsed.content).toBe('Answer text')
expect(parsed.references).toEqual([{ id: 1, title: 'Document 1' }])
})
it('should hide incomplete metadata trailer from the visible content', () => {
const parsed = parseChatResponse(
`Answer text${CHAT_METADATA_DELIMITER}{"references"`
)
expect(parsed.content).toBe('Answer text')
expect(parsed.references).toBeUndefined()
})
})
+40
View File
@@ -11,6 +11,46 @@ export interface ChatMessage {
role: 'user' | 'assistant'
content: string
isStreaming?: boolean
references?: ChatReference[]
}
export interface ChatReference {
id: number
title: string
}
export interface ParsedChatResponse {
content: string
references?: ChatReference[]
}
export const CHAT_METADATA_DELIMITER = '\n\n__PAPERLESS_CHAT_METADATA__'
export function parseChatResponse(response: string): ParsedChatResponse {
const delimiterIndex = response.indexOf(CHAT_METADATA_DELIMITER)
if (delimiterIndex === -1) {
return { content: response }
}
const metadataString = response.slice(
delimiterIndex + CHAT_METADATA_DELIMITER.length
)
try {
const metadata = JSON.parse(metadataString) as {
references?: ChatReference[]
}
return {
content: response.slice(0, delimiterIndex),
references: metadata.references ?? [],
}
} catch {
return {
content: response.slice(0, delimiterIndex),
}
}
}
@Injectable({