Files
ZY-Agent/web/src/components/deer-flow/resource-suggestion.tsx
T
JeffJiang 4ddd659d8d feat: rag retrieving tool call result display (#263)
* feat: local search tool call result display

* chore: add file copyright

* fix: miss edit plan interrupt feedback

* feat: disable pasting html into input box
2025-05-29 19:52:34 +08:00

87 lines
2.1 KiB
TypeScript

// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
// SPDX-License-Identifier: MIT
import type { MentionOptions } from "@tiptap/extension-mention";
import { ReactRenderer } from "@tiptap/react";
import {
ResourceMentions,
type ResourceMentionsProps,
} from "./resource-mentions";
import type { Instance, Props } from "tippy.js";
import tippy from "tippy.js";
import { resolveServiceURL } from "~/core/api/resolve-service-url";
import type { Resource } from "~/core/messages";
export const resourceSuggestion: MentionOptions["suggestion"] = {
items: ({ query }) => {
return fetch(resolveServiceURL(`rag/resources?query=${query}`), {
method: "GET",
})
.then((res) => res.json())
.then((res) => {
return res.resources as Array<Resource>;
})
.catch((err) => {
return [];
});
},
render: () => {
let reactRenderer: ReactRenderer<
{ onKeyDown: (args: { event: KeyboardEvent }) => boolean },
ResourceMentionsProps
>;
let popup: Instance<Props>[] | null = null;
return {
onStart: (props) => {
if (!props.clientRect) {
return;
}
reactRenderer = new ReactRenderer(ResourceMentions, {
props,
editor: props.editor,
});
popup = tippy("body", {
getReferenceClientRect: props.clientRect as any,
appendTo: () => document.body,
content: reactRenderer.element,
showOnCreate: true,
interactive: true,
trigger: "manual",
placement: "top-start",
});
},
onUpdate(props) {
reactRenderer.updateProps(props);
if (!props.clientRect) {
return;
}
popup?.[0]?.setProps({
getReferenceClientRect: props.clientRect as any,
});
},
onKeyDown(props) {
if (props.event.key === "Escape") {
popup?.[0]?.hide();
return true;
}
return reactRenderer.ref?.onKeyDown(props) ?? false;
},
onExit() {
popup?.[0]?.destroy();
reactRenderer.destroy();
},
};
},
};