-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: feedback and add chat to langfuse dataset (#163)
* feat: feedback * support add chat to langfuse * update
- Loading branch information
Showing
21 changed files
with
568 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,20 @@ | ||
DROP TABLE knowledge_graph_feedback; | ||
DROP TABLE feedback; | ||
|
||
CREATE TABLE knowledge_graph_feedback | ||
CREATE TABLE feedback | ||
( | ||
id INTEGER NOT NULL AUTO_INCREMENT, | ||
trace_id BINARY(16) NOT NULL COMMENT 'Langfuse trace ID (UUID)', | ||
detail JSON NOT NULL COMMENT 'Map, key is source URL, value is `like` or `dislike`.', | ||
comment TEXT NOT NULL COMMENT 'Comments from user', | ||
created_by VARCHAR(32) NOT NULL COMMENT 'User id', | ||
created_at DATETIME NOT NULL COMMENT 'User submit feedback at', | ||
reported_at DATETIME NULL COMMENT 'Reported to graph.tidb.ai', | ||
report_error VARCHAR(512) NULL COMMENT 'Report failure reason if reporting failed.', | ||
id INTEGER NOT NULL AUTO_INCREMENT, | ||
chat_id INTEGER NOT NULL, | ||
message_id INTEGER NOT NULL, | ||
trace_id BINARY(16) NOT NULL COMMENT 'Langfuse trace ID (UUID)', | ||
action ENUM ('like', 'dislike') NOT NULL, | ||
comment TEXT NOT NULL COMMENT 'Comments from user', | ||
created_by VARCHAR(32) NOT NULL COMMENT 'User id', | ||
created_at DATETIME NOT NULL COMMENT 'User submit feedback at', | ||
knowledge_graph_detail JSON NOT NULL COMMENT 'Map, key is source URL, value is `like` or `dislike`.', | ||
knowledge_graph_reported_at DATETIME NULL COMMENT 'Reported to graph.tidb.ai', | ||
knowledge_graph_report_error TEXT NULL COMMENT 'Report failure reason if reporting failed.', | ||
PRIMARY KEY (id), | ||
UNIQUE INDEX (trace_id, created_by), | ||
INDEX (created_at, reported_at) | ||
INDEX (created_at, knowledge_graph_reported_at), | ||
INDEX (chat_id, message_id) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
'use client'; | ||
|
||
import { AdminPageHeading } from '@/components/admin-page-heading'; | ||
import { DataTableRemote } from '@/components/data-table-remote'; | ||
import type { Feedback } from '@/core/repositories/feedback'; | ||
import type { ColumnDef } from '@tanstack/react-table'; | ||
import { createColumnHelper } from '@tanstack/table-core'; | ||
import { format } from 'date-fns'; | ||
import { LinkIcon, ThumbsDownIcon, ThumbsUpIcon } from 'lucide-react'; | ||
import Link from 'next/link'; | ||
|
||
export default function FeedbackPage () { | ||
return ( | ||
<> | ||
<AdminPageHeading title="Feedbacks" /> | ||
<DataTableRemote<Feedback & { chat_key: string, chat_title: string }, any> | ||
idColumn="id" | ||
api="/api/v1/feedbacks" | ||
columns={columns} | ||
/> | ||
</> | ||
); | ||
} | ||
|
||
const helper = createColumnHelper<Feedback & { chat_key: string, chat_title: string }>(); | ||
const columns: ColumnDef<Feedback & { chat_key: string, chat_title: string }, any>[] = [ | ||
helper.accessor('id', {}), | ||
helper.accessor('chat_key', { | ||
id: 'go_to_chat', | ||
header: 'chat', | ||
cell: (cell) => ( | ||
<Link href={`/c/${encodeURIComponent(cell.getValue())}`}> | ||
<LinkIcon className="w-3 h-3 mr-1 inline-block" /> | ||
{cell.row.original.chat_title} | ||
</Link> | ||
), | ||
}), | ||
helper.accessor('action', { | ||
cell: (cell) => { | ||
switch (cell.getValue()) { | ||
case 'like': | ||
return <span className="text-green-500 flex items-center gap-1"><ThumbsUpIcon className="w-3 h-3 inline-block" /> Like</span>; | ||
case 'dislike': | ||
return <span className="text-red-500 flex items-center gap-1"><ThumbsDownIcon className="w-3 h-3 inline-block" /> Dislike</span>; | ||
} | ||
}, | ||
}), | ||
helper.accessor('comment', {}), | ||
helper.accessor('created_by', {}), | ||
helper.accessor('created_at', { | ||
cell: cell => <time>{format(cell.getValue(), 'yyyy-MM-dd HH:mm:ss')}</time>, | ||
}), | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { authGuard } from '@/lib/auth-server'; | ||
import FeedbackPage from './page.client'; | ||
|
||
export default async function ServerDocumentsPage () { | ||
await authGuard('admin'); | ||
|
||
return ( | ||
<FeedbackPage /> | ||
); | ||
} | ||
|
||
export const dynamic = 'force-dynamic'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/app/api/v1/chats/[id]/messages/[messageId]/trace/datasets/route.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { getChat, getChatMessage } from '@/core/repositories/chat'; | ||
import { getTraceId } from '@/core/services/feedback/utils'; | ||
import { handleErrors } from '@/lib/fetch'; | ||
import type { LangfuseDatasetsResponse } from '@/lib/langfuse/types'; | ||
import { defineHandler } from '@/lib/next/handler'; | ||
import { Langfuse } from 'langfuse'; | ||
import { notFound } from 'next/navigation'; | ||
import z from 'zod'; | ||
|
||
export const GET = defineHandler({ | ||
params: z.object({ | ||
id: z.coerce.number(), | ||
messageId: z.coerce.number(), | ||
}), | ||
}, async ({ params }) => { | ||
const chat = await getChat(params.id); | ||
const message = await getChatMessage(params.messageId); | ||
|
||
if (!chat || !message) { | ||
notFound(); | ||
} | ||
|
||
if (!message.trace_url) { | ||
notFound(); | ||
} | ||
|
||
const traceId = getTraceId(message.trace_url); | ||
|
||
const datasets: LangfuseDatasetsResponse = await fetch(`https://us.cloud.langfuse.com/api/public/datasets`, { | ||
method: 'GET', | ||
headers: { | ||
Authorization: `Basic ${btoa(`${process.env.LANGFUSE_PUBLIC_KEY}:${process.env.LANGFUSE_SECRET_KEY}`)}`, | ||
}, | ||
cache: 'no-cache', | ||
}).then(handleErrors).then(res => res.json()); | ||
|
||
const includedDatasets: string[] = []; | ||
const client = new Langfuse(); | ||
|
||
await Promise.all(datasets.data.map(async dataset => { | ||
const datasetDetails = await client.getDataset(dataset.name); | ||
for (let item of datasetDetails.items) { | ||
if ((item as any).sourceTraceId === traceId) { | ||
includedDatasets.push(datasetDetails.name); | ||
break; | ||
} | ||
} | ||
})); | ||
|
||
return includedDatasets; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { listFeedbacks } from '@/core/repositories/feedback'; | ||
import { toPageRequest } from '@/lib/database'; | ||
import { defineHandler } from '@/lib/next/handler'; | ||
import z from 'zod'; | ||
|
||
export const GET = defineHandler({ | ||
searchParams: z.object({ | ||
chat_id: z.coerce.number().optional(), | ||
message_id: z.coerce.number().optional(), | ||
}), | ||
}, async ({ request, searchParams }) => { | ||
const { page, pageSize, sorting } = toPageRequest(request); | ||
|
||
return await listFeedbacks({ | ||
page, | ||
pageSize, | ||
sorting, | ||
...searchParams, | ||
}); | ||
}); | ||
|
||
export const dynamic = 'force-dynamic'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { handleErrors } from '@/lib/fetch'; | ||
import { defineHandler } from '@/lib/next/handler'; | ||
import { Langfuse } from 'langfuse'; | ||
import z from 'zod'; | ||
|
||
export const POST = defineHandler({ | ||
auth: 'admin', | ||
params: z.object({ | ||
name: z.string(), | ||
}), | ||
body: z.object({ | ||
traceId: z.string(), | ||
}), | ||
}, async ({ params, body }) => { | ||
const trace = await fetch(`https://us.cloud.langfuse.com/api/public/traces/${body.traceId}`, { | ||
method: 'GET', | ||
headers: { | ||
Authorization: `Basic ${btoa(`${process.env.LANGFUSE_PUBLIC_KEY}:${process.env.LANGFUSE_SECRET_KEY}`)}`, | ||
}, | ||
cache: 'no-cache', | ||
}).then(handleErrors).then(res => res.json()); | ||
|
||
return await new Langfuse().createDatasetItem({ | ||
datasetName: params.name, | ||
input: trace.input, | ||
metadata: trace.metadata, | ||
expectedOutput: trace.output, | ||
sourceTraceId: body.traceId, | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { handleErrors } from '@/lib/fetch'; | ||
import { defineHandler } from '@/lib/next/handler'; | ||
|
||
export const GET = defineHandler({ | ||
auth: 'admin', | ||
}, async ({}) => { | ||
const response = await fetch(`https://us.cloud.langfuse.com/api/public/datasets`, { | ||
method: 'GET', | ||
headers: { | ||
Authorization: `Basic ${btoa(`${process.env.LANGFUSE_PUBLIC_KEY}:${process.env.LANGFUSE_SECRET_KEY}`)}`, | ||
}, | ||
}).then(handleErrors); | ||
|
||
return await response.json() | ||
}); | ||
|
||
export const dynamic = 'force-dynamic'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.