|
2 | 2 | createErrorResult, |
3 | 3 | createSuccessResult, |
4 | 4 | type ApiResult, |
5 | | - type AppErrorCode |
| 5 | + type AppErrorCode, |
| 6 | + type EvidenceKind, |
| 7 | + type EvidenceRef |
6 | 8 | } from "@datafoundry/contracts"; |
7 | 9 | import { |
8 | 10 | createModelProviderFromEnv, |
@@ -1659,17 +1661,27 @@ const handleArtifactRequest = async ( |
1659 | 1661 | }); |
1660 | 1662 | }; |
1661 | 1663 |
|
1662 | | -const conversationMessageDto = (message: ConversationMessageRecord, visiblePosition = message.position): Record<string, unknown> => ({ |
| 1664 | +const conversationMessageDto = ( |
| 1665 | + message: ConversationMessageRecord, |
| 1666 | + visiblePosition = message.position |
| 1667 | +): Record<string, unknown> => ({ |
1663 | 1668 | id: message.id, |
1664 | 1669 | runId: message.run_id, |
1665 | 1670 | role: message.role, |
1666 | 1671 | source: message.source, |
1667 | 1672 | ...(message.message_id ? { messageId: message.message_id } : {}), |
1668 | 1673 | contentText: message.content_text, |
| 1674 | + ...conversationMessageEvidenceRefsDto(message), |
1669 | 1675 | position: visiblePosition, |
1670 | 1676 | createdAt: message.created_at |
1671 | 1677 | }); |
1672 | 1678 |
|
| 1679 | +const conversationMessageEvidenceRefsDto = (message: ConversationMessageRecord): Record<string, unknown> => { |
| 1680 | + const content = parseRecord(message.content_json); |
| 1681 | + const refs = evidenceRefsFromUnknown(content.evidenceRefs ?? content.evidence_refs); |
| 1682 | + return refs.length > 0 ? { evidenceRefs: refs } : {}; |
| 1683 | +}; |
| 1684 | + |
1673 | 1685 | const sessionListDto = (session: SessionRecord): Record<string, unknown> => ({ |
1674 | 1686 | id: session.id, |
1675 | 1687 | threadId: session.id, |
@@ -2801,6 +2813,33 @@ const clampInteger = (value: number, min: number, max: number, fallback: number) |
2801 | 2813 | Number.isInteger(value) ? Math.min(max, Math.max(min, value)) : fallback; |
2802 | 2814 | const stringArrayValue = (value: unknown): string[] => |
2803 | 2815 | Array.isArray(value) ? value.filter((item): item is string => typeof item === "string" && item.trim().length > 0) : []; |
| 2816 | +const evidenceRefsFromUnknown = (value: unknown): EvidenceRef[] => { |
| 2817 | + if (!Array.isArray(value)) { |
| 2818 | + return []; |
| 2819 | + } |
| 2820 | + return value.filter(isEvidenceRef); |
| 2821 | +}; |
| 2822 | +const isEvidenceRef = (value: unknown): value is EvidenceRef => { |
| 2823 | + if (!isRecord(value) || !isRecord(value.source)) { |
| 2824 | + return false; |
| 2825 | + } |
| 2826 | + return ( |
| 2827 | + typeof value.id === "string" && |
| 2828 | + isEvidenceKind(value.kind) && |
| 2829 | + typeof value.label === "string" && |
| 2830 | + typeof value.sessionId === "string" |
| 2831 | + ); |
| 2832 | +}; |
| 2833 | +const isEvidenceKind = (value: unknown): value is EvidenceKind => |
| 2834 | + value === "table" || |
| 2835 | + value === "chart" || |
| 2836 | + value === "report" || |
| 2837 | + value === "file" || |
| 2838 | + value === "sql" || |
| 2839 | + value === "schema" || |
| 2840 | + value === "preview" || |
| 2841 | + value === "knowledge" || |
| 2842 | + value === "step"; |
2804 | 2843 | const parseRecord = (value: string): Record<string, unknown> => { |
2805 | 2844 | const parsed: unknown = JSON.parse(value); |
2806 | 2845 | return isRecord(parsed) ? parsed : {}; |
|
0 commit comments