feat(ai): persist raw tool execution results in postgres to enable fine-tuning dataset extraction
This commit is contained in:
@@ -77,15 +77,23 @@ export default function SessionViewer() {
|
|||||||
session_id: sessionId,
|
session_id: sessionId,
|
||||||
title: thread.title,
|
title: thread.title,
|
||||||
created_at: thread.createdAt,
|
created_at: thread.createdAt,
|
||||||
messages: messages.map((m) => ({
|
messages: messages.map((m: any) => ({
|
||||||
role: m.role,
|
role: m.role,
|
||||||
content:
|
content:
|
||||||
m.content || (m.textSegments ? m.textSegments.join("\n\n") : ""),
|
m.content || (m.textSegments ? m.textSegments.join("\n\n") : ""),
|
||||||
tool_calls: m.toolCalls
|
tool_calls: m.toolCalls
|
||||||
? m.toolCalls.map((tc) => ({
|
? m.toolCalls.map((tc: any) => {
|
||||||
name: tc.name,
|
const rawResult = m._rawToolResults?.find(
|
||||||
arguments: tc.args,
|
(tr: any) =>
|
||||||
}))
|
tr.name === tc.name &&
|
||||||
|
JSON.stringify(tr.args) === JSON.stringify(tc.args),
|
||||||
|
)?.result;
|
||||||
|
return {
|
||||||
|
name: tc.name,
|
||||||
|
arguments: tc.args,
|
||||||
|
result: rawResult,
|
||||||
|
};
|
||||||
|
})
|
||||||
: undefined,
|
: undefined,
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -723,14 +723,38 @@ export async function POST(request: Request) {
|
|||||||
// segmentation it shows during streaming. Older messages
|
// segmentation it shows during streaming. Older messages
|
||||||
// (pre-this-fix) won't have textSegments and fall back to
|
// (pre-this-fix) won't have textSegments and fall back to
|
||||||
// single-bubble content rendering.
|
// single-bubble content rendering.
|
||||||
const finalMsg: ChatMessage & { textSegments?: string[] } = {
|
const finalMsg: ChatMessage & {
|
||||||
|
textSegments?: string[];
|
||||||
|
_rawToolResults?: Array<{ name: string; args: any; result: string }>;
|
||||||
|
} = {
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
content: assistantText,
|
content: assistantText,
|
||||||
toolCalls: assistantToolCalls.length ? assistantToolCalls : undefined,
|
toolCalls: assistantToolCalls.length ? assistantToolCalls : undefined,
|
||||||
textSegments: assistantTextSegments.length
|
textSegments: assistantTextSegments.length
|
||||||
? assistantTextSegments
|
? assistantTextSegments
|
||||||
: undefined,
|
: undefined,
|
||||||
|
_rawToolResults: assistantToolCalls.length ? [] : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Option 1 implemented: Save the raw tool results directly into the database row
|
||||||
|
// alongside the assistant message so it can be extracted later for fine-tuning.
|
||||||
|
if (finalMsg._rawToolResults) {
|
||||||
|
// We slice out the tool messages from the internal messages array we just built
|
||||||
|
// during the loop and attach them to the final row payload.
|
||||||
|
const toolResults = messages.filter((m) => m.role === "tool");
|
||||||
|
finalMsg._rawToolResults = assistantToolCalls.map((tc) => {
|
||||||
|
const tr = toolResults.find((m) => m.toolCallId === tc.id);
|
||||||
|
return {
|
||||||
|
name: tc.name,
|
||||||
|
args: tc.args,
|
||||||
|
result:
|
||||||
|
typeof tr?.content === "string"
|
||||||
|
? tr.content
|
||||||
|
: JSON.stringify(tr?.content || ""),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await query(
|
await query(
|
||||||
`INSERT INTO fs_chat_messages (thread_id, user_id, data) VALUES ($1, $2, $3)`,
|
`INSERT INTO fs_chat_messages (thread_id, user_id, data) VALUES ($1, $2, $3)`,
|
||||||
[thread_id, email, JSON.stringify(finalMsg)],
|
[thread_id, email, JSON.stringify(finalMsg)],
|
||||||
|
|||||||
Reference in New Issue
Block a user