Skip to content

Commit 26a7b2f

Browse files
committed
Add evidence reference flow
1 parent 49994b6 commit 26a7b2f

23 files changed

Lines changed: 1375 additions & 7 deletions

apps/api/src/config-api.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import {
22
createErrorResult,
33
createSuccessResult,
44
type ApiResult,
5-
type AppErrorCode
5+
type AppErrorCode,
6+
type EvidenceKind,
7+
type EvidenceRef
68
} from "@datafoundry/contracts";
79
import {
810
createModelProviderFromEnv,
@@ -1659,17 +1661,27 @@ const handleArtifactRequest = async (
16591661
});
16601662
};
16611663

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> => ({
16631668
id: message.id,
16641669
runId: message.run_id,
16651670
role: message.role,
16661671
source: message.source,
16671672
...(message.message_id ? { messageId: message.message_id } : {}),
16681673
contentText: message.content_text,
1674+
...conversationMessageEvidenceRefsDto(message),
16691675
position: visiblePosition,
16701676
createdAt: message.created_at
16711677
});
16721678

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+
16731685
const sessionListDto = (session: SessionRecord): Record<string, unknown> => ({
16741686
id: session.id,
16751687
threadId: session.id,
@@ -2801,6 +2813,33 @@ const clampInteger = (value: number, min: number, max: number, fallback: number)
28012813
Number.isInteger(value) ? Math.min(max, Math.max(min, value)) : fallback;
28022814
const stringArrayValue = (value: unknown): string[] =>
28032815
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";
28042843
const parseRecord = (value: string): Record<string, unknown> => {
28052844
const parsed: unknown = JSON.parse(value);
28062845
return isRecord(parsed) ? parsed : {};

apps/api/src/conversation-memory.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { EventType, type BaseEvent, type Message, type RunAgentInput } from "@ag-ui/client";
22
import { ContextTokenCounter, type ConversationMemoryBridge } from "@datafoundry/agent-runtime";
3+
import type { EvidenceRef } from "@datafoundry/contracts";
34
import {
45
type ConversationMessageRecord,
56
type ConversationMessageRepository,
@@ -104,6 +105,7 @@ type BuildConversationMessagesInput = {
104105

105106
type PersistCurrentUserMessageInput = {
106107
currentUserText: string;
108+
evidenceRefs?: EvidenceRef[];
107109
repository: ConversationMessageRepository;
108110
runId: string;
109111
runInput: RunAgentInput;
@@ -203,11 +205,13 @@ export class ConversationMemoryService {
203205

204206
persistCurrentUserMessage(input: {
205207
currentUserText: string;
208+
evidenceRefs?: EvidenceRef[];
206209
runId: string;
207210
runInput: RunAgentInput;
208211
}): ConversationMessageRecord {
209212
return persistCurrentUserMessage({
210213
currentUserText: input.currentUserText,
214+
evidenceRefs: input.evidenceRefs ?? [],
211215
repository: this.input.repository,
212216
runId: input.runId,
213217
runInput: input.runInput,
@@ -307,7 +311,10 @@ export const persistCurrentUserMessage = (input: PersistCurrentUserMessageInput)
307311
role: "user",
308312
source: "client",
309313
content_text: input.currentUserText,
310-
content: { text: input.currentUserText },
314+
content: {
315+
text: input.currentUserText,
316+
...((input.evidenceRefs?.length ?? 0) > 0 ? { evidenceRefs: input.evidenceRefs } : {})
317+
},
311318
...(message?.id ? { message_id: message.id } : {})
312319
});
313320
};

0 commit comments

Comments
 (0)