Skip to content
Snippets Groups Projects
Commit ddf3aef7 authored by Thuc Pham's avatar Thuc Pham
Browse files

remove node path

parent 48188ca3
No related branches found
No related tags found
No related merge requests found
...@@ -15,7 +15,7 @@ export type InterpreterToolParams = { ...@@ -15,7 +15,7 @@ export type InterpreterToolParams = {
fileServerURLPrefix?: string; fileServerURLPrefix?: string;
}; };
export type InterpreterToolOuput = { export type InterpreterToolOutput = {
isError: boolean; isError: boolean;
logs: Logs; logs: Logs;
extraResult: InterpreterExtraResult[]; extraResult: InterpreterExtraResult[];
...@@ -88,7 +88,7 @@ export class InterpreterTool implements BaseTool<InterpreterParameter> { ...@@ -88,7 +88,7 @@ export class InterpreterTool implements BaseTool<InterpreterParameter> {
return this.codeInterpreter; return this.codeInterpreter;
} }
public async codeInterpret(code: string): Promise<InterpreterToolOuput> { public async codeInterpret(code: string): Promise<InterpreterToolOutput> {
console.log( console.log(
`\n${"=".repeat(50)}\n> Running following AI-generated code:\n${code}\n${"=".repeat(50)}`, `\n${"=".repeat(50)}\n> Running following AI-generated code:\n${code}\n${"=".repeat(50)}`,
); );
...@@ -96,7 +96,7 @@ export class InterpreterTool implements BaseTool<InterpreterParameter> { ...@@ -96,7 +96,7 @@ export class InterpreterTool implements BaseTool<InterpreterParameter> {
const exec = await interpreter.notebook.execCell(code); const exec = await interpreter.notebook.execCell(code);
if (exec.error) console.error("[Code Interpreter error]", exec.error); if (exec.error) console.error("[Code Interpreter error]", exec.error);
const extraResult = await this.getExtraResult(exec.results[0]); const extraResult = await this.getExtraResult(exec.results[0]);
const result: InterpreterToolOuput = { const result: InterpreterToolOutput = {
isError: !!exec.error, isError: !!exec.error,
logs: exec.logs, logs: exec.logs,
extraResult, extraResult,
...@@ -104,7 +104,7 @@ export class InterpreterTool implements BaseTool<InterpreterParameter> { ...@@ -104,7 +104,7 @@ export class InterpreterTool implements BaseTool<InterpreterParameter> {
return result; return result;
} }
async call(input: InterpreterParameter): Promise<InterpreterToolOuput> { async call(input: InterpreterParameter): Promise<InterpreterToolOutput> {
const result = await this.codeInterpret(input.code); const result = await this.codeInterpret(input.code);
await this.codeInterpreter?.close(); await this.codeInterpreter?.close();
return result; return result;
......
...@@ -48,9 +48,11 @@ class _SourceNodes(BaseModel): ...@@ -48,9 +48,11 @@ class _SourceNodes(BaseModel):
if not url: if not url:
file_name = metadata.get("file_name") file_name = metadata.get("file_name")
if file_name: url_prefix = os.getenv("FILESERVER_URL_PREFIX")
file_server_url_prefix = os.getenv("FILESERVER_URL_PREFIX", "") if not url_prefix:
url = f"{file_server_url_prefix}/data/{file_name}" print("Warning: FILESERVER_URL_PREFIX not set in environment variables")
if file_name and url_prefix:
url = f"{url_prefix}/data/{file_name}"
return cls( return cls(
id=source_node.node.node_id, id=source_node.node.node_id,
......
...@@ -21,9 +21,14 @@ function getNodeUrl(metadata: Metadata) { ...@@ -21,9 +21,14 @@ function getNodeUrl(metadata: Metadata) {
const url = metadata["URL"]; const url = metadata["URL"];
if (url) return url; if (url) return url;
const fileName = metadata["file_name"]; const fileName = metadata["file_name"];
if (!process.env.FILESERVER_URL_PREFIX) {
console.warn(
"FILESERVER_URL_PREFIX is not set. File URLs will not be generated.",
);
return undefined;
}
if (fileName) { if (fileName) {
const fileServerUrlPrefix = process.env.FILESERVER_URL_PREFIX || ""; return `${process.env.FILESERVER_URL_PREFIX}/data/${fileName}`;
return `${fileServerUrlPrefix}/data/${fileName}`;
} }
return undefined; return undefined;
} }
......
...@@ -2,11 +2,10 @@ import { Check, Copy } from "lucide-react"; ...@@ -2,11 +2,10 @@ import { Check, Copy } from "lucide-react";
import { useMemo } from "react"; import { useMemo } from "react";
import { Button } from "../button"; import { Button } from "../button";
import { HoverCard, HoverCardContent, HoverCardTrigger } from "../hover-card"; import { HoverCard, HoverCardContent, HoverCardTrigger } from "../hover-card";
import { SourceData, SourceNode } from "./index"; import { SourceData } from "./index";
import { useCopyToClipboard } from "./use-copy-to-clipboard"; import { useCopyToClipboard } from "./use-copy-to-clipboard";
import PdfDialog from "./widgets/PdfDialog"; import PdfDialog from "./widgets/PdfDialog";
const DATA_SOURCE_FOLDER = "data";
const SCORE_THRESHOLD = 0.3; const SCORE_THRESHOLD = 0.3;
function SourceNumberButton({ index }: { index: number }) { function SourceNumberButton({ index }: { index: number }) {
...@@ -17,45 +16,11 @@ function SourceNumberButton({ index }: { index: number }) { ...@@ -17,45 +16,11 @@ function SourceNumberButton({ index }: { index: number }) {
); );
} }
enum NODE_TYPE {
URL,
FILE,
UNKNOWN,
}
type NodeInfo = { type NodeInfo = {
id: string; id: string;
type: NODE_TYPE;
path?: string;
url?: string; url?: string;
}; };
function getNodeInfo(node: SourceNode): NodeInfo {
if (typeof node.metadata["URL"] === "string") {
return {
id: node.id,
type: NODE_TYPE.URL,
path: node.url,
url: node.url,
};
}
if (typeof node.metadata["file_path"] === "string") {
const fileName = node.metadata["file_name"] as string;
const filePath = `${DATA_SOURCE_FOLDER}/${fileName}`;
return {
id: node.id,
type: NODE_TYPE.FILE,
path: filePath,
url: node.url,
};
}
return {
id: node.id,
type: NODE_TYPE.UNKNOWN,
};
}
export function ChatSources({ data }: { data: SourceData }) { export function ChatSources({ data }: { data: SourceData }) {
const sources: NodeInfo[] = useMemo(() => { const sources: NodeInfo[] = useMemo(() => {
// aggregate nodes by url or file_path (get the highest one by score) // aggregate nodes by url or file_path (get the highest one by score)
...@@ -65,8 +30,11 @@ export function ChatSources({ data }: { data: SourceData }) { ...@@ -65,8 +30,11 @@ export function ChatSources({ data }: { data: SourceData }) {
.filter((node) => (node.score ?? 1) > SCORE_THRESHOLD) .filter((node) => (node.score ?? 1) > SCORE_THRESHOLD)
.sort((a, b) => (b.score ?? 1) - (a.score ?? 1)) .sort((a, b) => (b.score ?? 1) - (a.score ?? 1))
.forEach((node) => { .forEach((node) => {
const nodeInfo = getNodeInfo(node); const nodeInfo = {
const key = nodeInfo.path ?? nodeInfo.id; // use id as key for UNKNOWN type id: node.id,
url: node.url,
};
const key = nodeInfo.url ?? nodeInfo.id; // use id as key for UNKNOWN type
if (!nodesByPath[key]) { if (!nodesByPath[key]) {
nodesByPath[key] = nodeInfo; nodesByPath[key] = nodeInfo;
} }
...@@ -82,13 +50,12 @@ export function ChatSources({ data }: { data: SourceData }) { ...@@ -82,13 +50,12 @@ export function ChatSources({ data }: { data: SourceData }) {
<span className="font-semibold">Sources:</span> <span className="font-semibold">Sources:</span>
<div className="inline-flex gap-1 items-center"> <div className="inline-flex gap-1 items-center">
{sources.map((nodeInfo: NodeInfo, index: number) => { {sources.map((nodeInfo: NodeInfo, index: number) => {
if (nodeInfo.path?.endsWith(".pdf")) { if (nodeInfo.url?.endsWith(".pdf")) {
return ( return (
<PdfDialog <PdfDialog
key={nodeInfo.id} key={nodeInfo.id}
documentId={nodeInfo.id} documentId={nodeInfo.id}
url={nodeInfo.url!} url={nodeInfo.url!}
path={nodeInfo.path}
trigger={<SourceNumberButton index={index} />} trigger={<SourceNumberButton index={index} />}
/> />
); );
...@@ -114,13 +81,13 @@ export function ChatSources({ data }: { data: SourceData }) { ...@@ -114,13 +81,13 @@ export function ChatSources({ data }: { data: SourceData }) {
function NodeInfo({ nodeInfo }: { nodeInfo: NodeInfo }) { function NodeInfo({ nodeInfo }: { nodeInfo: NodeInfo }) {
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 1000 }); const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 1000 });
if (nodeInfo.type !== NODE_TYPE.UNKNOWN) { if (nodeInfo.url) {
// this is a node generated by the web loader or file loader, // this is a node generated by the web loader or file loader,
// add a link to view its URL and a button to copy the URL to the clipboard // add a link to view its URL and a button to copy the URL to the clipboard
return ( return (
<div className="flex items-center my-2"> <div className="flex items-center my-2">
<a className="hover:text-blue-900" href={nodeInfo.url} target="_blank"> <a className="hover:text-blue-900" href={nodeInfo.url} target="_blank">
<span>{nodeInfo.path}</span> <span>{nodeInfo.url}</span>
</a> </a>
<Button <Button
onClick={() => copyToClipboard(nodeInfo.url!)} onClick={() => copyToClipboard(nodeInfo.url!)}
......
...@@ -12,7 +12,6 @@ import { ...@@ -12,7 +12,6 @@ import {
export interface PdfDialogProps { export interface PdfDialogProps {
documentId: string; documentId: string;
path: string;
url: string; url: string;
trigger: React.ReactNode; trigger: React.ReactNode;
} }
...@@ -26,13 +25,13 @@ export default function PdfDialog(props: PdfDialogProps) { ...@@ -26,13 +25,13 @@ export default function PdfDialog(props: PdfDialogProps) {
<div className="space-y-2"> <div className="space-y-2">
<DrawerTitle>PDF Content</DrawerTitle> <DrawerTitle>PDF Content</DrawerTitle>
<DrawerDescription> <DrawerDescription>
File path:{" "} File URL:{" "}
<a <a
className="hover:text-blue-900" className="hover:text-blue-900"
href={props.url} href={props.url}
target="_blank" target="_blank"
> >
{props.path} {props.url}
</a> </a>
</DrawerDescription> </DrawerDescription>
</div> </div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment