[PAI-633] Chore workspace info added in apis (#3862)

* chore: sending workspace info for all the pi apis

* fix: message scrolling for chat

* fix: border color for markdown table

* fix: added workspace_id in queue-answer api

* fix: workspaceId types

* fix: refactor
This commit is contained in:
Akshita Goyal
2025-08-12 13:13:10 +05:30
committed by GitHub
parent 58bb85496e
commit 06e20ca01c
13 changed files with 176 additions and 81 deletions
@@ -1,10 +1,12 @@
import { useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { Copy, ThumbsDown, ThumbsUp } from "lucide-react";
import { Loader, PiIcon, setToast, TOAST_TYPE, Tooltip } from "@plane/ui";
import { cn, copyTextToClipboard } from "@plane/utils";
import { useWorkspace } from "@/hooks/store/use-workspace";
import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
import { EFeedback } from "@/plane-web/types";
import { FeedbackModal } from "../input/feedback-modal";
@@ -21,9 +23,12 @@ type TProps = {
isLatest?: boolean;
};
export const AiMessage = observer((props: TProps) => {
// store
const { message = "", reasoning, isPiThinking = false, id, isLoading = false, feedback, isLatest } = props;
// store
const { workspaceSlug } = useParams();
const { sendFeedback, activeChatId } = usePiChat();
const { getWorkspaceBySlug } = useWorkspace();
const workspaceId = getWorkspaceBySlug(workspaceSlug as string)?.id;
// state
const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);
@@ -38,7 +43,7 @@ export const AiMessage = observer((props: TProps) => {
};
const handleFeedback = async (feedback: EFeedback, feedbackMessage?: string) => {
try {
await sendFeedback(activeChatId, parseInt(id), feedback, feedbackMessage);
await sendFeedback(activeChatId, parseInt(id), feedback, workspaceId, feedbackMessage);
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Feedback sent!",
@@ -74,12 +79,12 @@ export const AiMessage = observer((props: TProps) => {
</a>
),
table: ({ children }) => (
<div className="overflow-x-auto w-full my-4">
<div className="overflow-x-auto w-full my-4 border-custom-border-200">
<table className="min-w-full border-collapse">{children}</table>
</div>
),
th: ({ children }) => <th className="px-2 py-3">{children}</th>,
td: ({ children }) => <td className="px-2 py-3">{children}</td>,
th: ({ children }) => <th className="px-2 py-3 border-custom-border-200">{children}</th>,
td: ({ children }) => <td className="px-2 py-3 border-custom-border-200">{children}</td>,
}}
>
{message}
@@ -4,6 +4,7 @@ import { IUser } from "@plane/types";
import { cn } from "@plane/utils";
import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
import { TDialogue } from "@/plane-web/types";
import { scrollIntoViewHelper } from "../helper";
import { AiMessage } from "./ai-message";
import { MyMessage } from "./my-message";
import { NewConversation } from "./new-converstaion";
@@ -58,6 +59,7 @@ export const Messages = observer((props: TProps) => {
//Always scroll to the latest message
if (!activeChat?.dialogue) return;
if (activeChat?.dialogue.length === 0) setHasMoreMessages(false);
scrollIntoViewHelper(`${activeChat?.dialogue?.length - 1}`);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeChat?.dialogue?.length]);
@@ -1,9 +1,11 @@
import { useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
import useSWR from "swr";
import { IUser } from "@plane/types";
import { Loader } from "@plane/ui";
import { cn } from "@plane/utils";
import { useWorkspace } from "@/hooks/store/use-workspace";
import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
import SystemPrompts from "../system-prompts";
@@ -16,8 +18,11 @@ type TProps = {
export const NewConversation = observer((props: TProps) => {
const { currentUser, isFullScreen, shouldRedirect = true, isProjectLevel = false } = props;
// store hooks
const { workspaceSlug } = useParams();
const { getTemplates } = usePiChat();
const { data: templates, isLoading } = useSWR("PI_TEMPLATES", () => getTemplates(), {
const { getWorkspaceBySlug } = useWorkspace();
const workspaceId = getWorkspaceBySlug(workspaceSlug as string)?.id;
const { data: templates, isLoading } = useSWR("PI_TEMPLATES", () => getTemplates(workspaceId), {
revalidateOnFocus: false,
revalidateIfStale: false,
errorRetryCount: 0,
+11 -4
View File
@@ -58,7 +58,7 @@ export const InputBox = observer((props: TProps) => {
const focusRef = useRef<TFocus>(focus);
const editorCommands = useRef<TEditCommands | null>(null);
useSWR(`PI_MODELS`, () => fetchModels(), {
useSWR(`PI_MODELS`, () => fetchModels(workspaceId), {
revalidateOnFocus: true,
revalidateIfStale: true,
errorRetryCount: 0,
@@ -72,17 +72,24 @@ export const InputBox = observer((props: TProps) => {
async (e?: React.FormEvent) => {
e?.preventDefault();
const query = editorCommands.current?.getHTML();
if (isLoadingRef.current || !query || isCommentEmpty(query)) return;
if (isLoadingRef.current || !query || isCommentEmpty(query) || !workspaceId) return;
if (!activeChatIdRef.current) {
isLoadingRef.current = true;
setIsInitializing(true);
const newChatId = await createNewChat(focusRef.current, isProjectLevel, workspaceId || "");
const newChatId = await createNewChat(focusRef.current, isProjectLevel, workspaceId);
activeChatIdRef.current = newChatId;
setIsInitializing(false);
// Don't redirect if we are in the floating chat window
if (shouldRedirect) router.push(`/${workspaceSlug}/${isProjectLevel ? "projects/" : ""}pi-chat/${newChatId}`);
}
getAnswer(activeChatIdRef.current, query, focusRef.current, isProjectLevel);
getAnswer(
activeChatIdRef.current,
query,
focusRef.current,
isProjectLevel,
workspaceSlug?.toString(),
workspaceId
);
editorCommands.current?.clear();
},
[editorCommands, getAnswer, activeChatId]
+3 -4
View File
@@ -34,12 +34,11 @@ export const PiChatLayout = observer((props: TProps) => {
const pathName = usePathname();
// derived states
const isFullScreen = pathName.includes("pi-chat") || isFullScreenProp;
const workspaceId = getWorkspaceBySlug(workspaceSlug as string)?.id;
useSWR(
workspaceSlug ? `PI_USER_THREADS_${workspaceSlug}_${isProjectLevel}` : null,
workspaceSlug
? () => fetchUserThreads(getWorkspaceBySlug(workspaceSlug as string)?.id || "", isProjectLevel)
: null,
workspaceSlug ? () => fetchUserThreads(workspaceId, isProjectLevel) : null,
{
revalidateOnFocus: false,
revalidateIfStale: false,
@@ -48,7 +47,7 @@ export const PiChatLayout = observer((props: TProps) => {
);
useSWR(
activeChatId ? `PI_ACTIVE_CHAT_${activeChatId}` : null,
activeChatId ? () => fetchChatById(activeChatId) : null,
activeChatId ? () => fetchChatById(activeChatId, workspaceId) : null,
{
revalidateOnFocus: false,
revalidateIfStale: false,
@@ -6,10 +6,11 @@ import { Pencil, Star, Trash } from "lucide-react";
import { useTranslation } from "@plane/i18n";
import { CustomMenu, EModalPosition, EModalWidth, ModalCore, setToast, TContextMenuItem, TOAST_TYPE } from "@plane/ui";
import { calculateTimeAgo, cn } from "@plane/utils";
import { useWorkspace } from "@/hooks/store/use-workspace";
import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
import { TUserThreads } from "@/plane-web/types";
import { ChatDeleteModal } from "../modals/delete-modal";
import { EditForm } from "../modals/edit-form";
import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
type TProps = {
thread: TUserThreads;
@@ -27,12 +28,15 @@ export const PiChatListItem = observer((props: TProps) => {
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
// hooks
const { favoriteChat, unfavoriteChat } = usePiChat();
const { getWorkspaceBySlug } = useWorkspace();
// derived
const workspaceId = getWorkspaceBySlug(workspaceSlug as string)?.id;
const handleFavorite = async () => {
if (thread.is_favorite) {
await unfavoriteChat(thread.chat_id);
await unfavoriteChat(thread.chat_id, workspaceId);
} else {
await favoriteChat(thread.chat_id);
await favoriteChat(thread.chat_id, workspaceId);
}
setToast({
title: thread.is_favorite ? t("favorite_removed_successfully") : t("favorite_created_successfully"),
@@ -65,7 +69,7 @@ export const PiChatListItem = observer((props: TProps) => {
<>
<ChatDeleteModal
chatId={thread.chat_id}
workspaceSlug={workspaceSlug?.toString() || ""}
workspaceSlug={workspaceSlug?.toString()}
isOpen={isDeleteModalOpen}
chatTitle={thread.title || ""}
handleClose={() => setIsDeleteModalOpen(false)}
@@ -80,6 +84,7 @@ export const PiChatListItem = observer((props: TProps) => {
chatId={thread.chat_id}
title={thread.title || ""}
handleModalClose={() => setIsEditModalOpen(false)}
workspaceId={workspaceId}
/>
</ModalCore>
<div className="flex justify-between items-end w-full" ref={parentRef}>
@@ -13,11 +13,12 @@ import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
type Props = {
chatId: string;
title: string;
workspaceId: string | undefined;
handleModalClose: () => void;
};
export const EditForm: React.FC<Props> = (props) => {
const { chatId, title, handleModalClose } = props;
const { chatId, title, handleModalClose, workspaceId } = props;
// hooks
const { isMobile } = usePlatformOS();
const { renameChat } = usePiChat();
@@ -31,7 +32,7 @@ export const EditForm: React.FC<Props> = (props) => {
e.preventDefault();
try {
setIsSubmitting(true);
await renameChat(chatId, newTitle);
await renameChat(chatId, newTitle, workspaceId);
setIsSubmitting(false);
setToast({
type: TOAST_TYPE.SUCCESS,
@@ -26,7 +26,7 @@ export const RightSidePanel = observer((props: TProps) => {
const { geUserThreadsByWorkspaceId, isLoadingThreads } = usePiChat();
const { getWorkspaceBySlug } = useWorkspace();
const workspaceId = workspaceSlug && getWorkspaceBySlug(workspaceSlug?.toString() || "")?.id;
const userThreads = geUserThreadsByWorkspaceId(workspaceId?.toString() || "");
const userThreads = geUserThreadsByWorkspaceId(workspaceId?.toString());
// filter user threads
const filteredUserThread =
@@ -6,6 +6,7 @@ import { useTranslation } from "@plane/i18n";
import { CustomMenu, EModalWidth, EModalPosition, ModalCore, setToast, TContextMenuItem, TOAST_TYPE } from "@plane/ui";
import { cn, joinUrlPath } from "@plane/utils";
import { SidebarNavItem } from "@/components/sidebar";
import { useWorkspace } from "@/hooks/store/use-workspace";
import { usePiChat } from "@/plane-web/hooks/store/use-pi-chat";
import { ChatDeleteModal } from "../modals/delete-modal";
import { EditForm } from "../modals/edit-form";
@@ -30,12 +31,14 @@ export const SidebarItem = observer((props: TProps) => {
const { t } = useTranslation();
// hooks
const { favoriteChat, unfavoriteChat } = usePiChat();
const { getWorkspaceBySlug } = useWorkspace();
const workspaceId = getWorkspaceBySlug(workspaceSlug as string)?.id;
const handleFavorite = async () => {
if (isFavorite) {
await unfavoriteChat(chatId);
await unfavoriteChat(chatId, workspaceId);
} else {
await favoriteChat(chatId);
await favoriteChat(chatId, workspaceId);
}
setToast({
title: isFavorite ? t("favorite_removed_successfully") : t("favorite_created_successfully"),
@@ -81,7 +84,12 @@ export const SidebarItem = observer((props: TProps) => {
position={EModalPosition.TOP}
width={EModalWidth.SM}
>
<EditForm chatId={chatId} title={title || ""} handleModalClose={() => setIsEditModalOpen(false)} />
<EditForm
chatId={chatId}
title={title || ""}
handleModalClose={() => setIsEditModalOpen(false)}
workspaceId={workspaceId}
/>
</ModalCore>{" "}
<div className="py-0.5 group/recent-chat">
<SidebarNavItem isActive={isActive} className="gap-0">
@@ -50,11 +50,11 @@ const SystemPrompts = (props: TSystemPrompt) => {
entityType: projectId ? "project_id" : "workspace_id",
entityIdentifier: projectId?.toString() || workspaceId?.toString() || "",
};
const newChatId = await createNewChat(focus, isProjectLevel, workspaceId || "");
const newChatId = await createNewChat(focus, isProjectLevel, workspaceId);
setIsInitializing("");
// Don't redirect if we are in the floating chat window
if (shouldRedirect) router.push(`/${workspaceSlug}/${isProjectLevel ? "projects/" : ""}pi-chat/${newChatId}`);
getAnswer(newChatId, prompt.text, focus, isProjectLevel);
getAnswer(newChatId, prompt.text, focus, isProjectLevel, workspaceSlug?.toString(), workspaceId?.toString());
};
const promptIcon = getIcon(prompt.type);
+47 -19
View File
@@ -70,8 +70,12 @@ export class PiChatService extends APIService {
}
// fetch templates
async listTemplates(): Promise<TTemplateResponse> {
return this.get(`/api/v1/chat/get-templates/`)
async listTemplates(workspaceId: string | undefined): Promise<TTemplateResponse> {
return this.get(`/api/v1/chat/get-templates/`, {
params: {
...(workspaceId && { workspace_id: workspaceId }),
},
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@@ -79,8 +83,11 @@ export class PiChatService extends APIService {
}
// generate title
async retrieveTitle(chatId: string): Promise<TTitleResponse> {
return this.post(`/api/v1/chat/generate-title/`, { chat_id: chatId })
async retrieveTitle(chatId: string, workspaceId: string | undefined): Promise<TTitleResponse> {
return this.post(`/api/v1/chat/generate-title/`, {
chat_id: chatId,
...(workspaceId && { workspace_id: workspaceId }),
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@@ -106,10 +113,11 @@ export class PiChatService extends APIService {
}
// get chat by id
async retrieveChat(chatId: string): Promise<TChatHistoryResponse> {
async retrieveChat(chatId: string, workspaceId: string | undefined): Promise<TChatHistoryResponse> {
return this.get(`/api/v1/chat/get-chat-history-object/`, {
params: {
chat_id: chatId,
...(workspaceId && { workspace_id: workspaceId }),
},
})
.then((response) => response?.data)
@@ -120,16 +128,16 @@ export class PiChatService extends APIService {
// get user threads
async listUserThreads(
workspaceId: string,
workspaceId: string | undefined,
is_project_chat: boolean,
cursor: string = "0"
): Promise<TUserThreadsResponse> {
return this.get(`/api/v1/chat/get-user-threads/`, {
params: {
per_page: 100,
workspace_id: workspaceId,
is_project_chat,
cursor,
...(workspaceId && { workspace_id: workspaceId }),
},
})
.then((response) => response?.data)
@@ -139,8 +147,12 @@ export class PiChatService extends APIService {
}
// get recent chats
async listRecentChats(): Promise<TUserThreadsResponse> {
return this.get(`/api/v1/chat/get-recent-user-threads/`)
async listRecentChats(workspaceId: string | undefined): Promise<TUserThreadsResponse> {
return this.get(`/api/v1/chat/get-recent-user-threads/`, {
params: {
...(workspaceId && { workspace_id: workspaceId }),
},
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@@ -148,8 +160,12 @@ export class PiChatService extends APIService {
}
// get models
async listAiModels(): Promise<TAiModelsResponse> {
return this.get(`/api/v1/chat/get-models/`)
async listAiModels(workspaceId?: string): Promise<TAiModelsResponse> {
return this.get(`/api/v1/chat/get-models/`, {
params: {
...(workspaceId && { workspace_id: workspaceId }),
},
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@@ -157,8 +173,11 @@ export class PiChatService extends APIService {
}
// favorite chat
async favoriteChat(chatId: string): Promise<void> {
return this.post(`/api/v1/chat/favorite-chat/`, { chat_id: chatId })
async favoriteChat(chatId: string, workspaceId: string | undefined): Promise<void> {
return this.post(`/api/v1/chat/favorite-chat/`, {
chat_id: chatId,
...(workspaceId && { workspace_id: workspaceId }),
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@@ -166,8 +185,11 @@ export class PiChatService extends APIService {
}
// unfavorite chat
async unfavoriteChat(chatId: string): Promise<void> {
return this.post(`/api/v1/chat/unfavorite-chat/`, { chat_id: chatId })
async unfavoriteChat(chatId: string, workspaceId: string | undefined): Promise<void> {
return this.post(`/api/v1/chat/unfavorite-chat/`, {
chat_id: chatId,
...(workspaceId && { workspace_id: workspaceId }),
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
@@ -175,9 +197,11 @@ export class PiChatService extends APIService {
}
// get favorite chats
async listFavoriteChats(workspaceId: string): Promise<TUserThreads[]> {
async listFavoriteChats(workspaceId: string | undefined): Promise<TUserThreads[]> {
return this.get(`/api/v1/chat/get-favorite-chats/`, {
params: { workspace_id: workspaceId },
params: {
...(workspaceId && { workspace_id: workspaceId }),
},
})
.then((response) => response?.data)
.catch((error) => {
@@ -186,8 +210,12 @@ export class PiChatService extends APIService {
}
// rename chat
async renameChat(chatId: string, title: string): Promise<void> {
return this.post(`/api/v1/chat/rename-chat/`, { chat_id: chatId, title })
async renameChat(chatId: string, title: string, workspaceId: string | undefined): Promise<void> {
return this.post(`/api/v1/chat/rename-chat/`, {
chat_id: chatId,
title,
...(workspaceId && { workspace_id: workspaceId }),
})
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
+65 -35
View File
@@ -41,26 +41,39 @@ export interface IPiChatStore {
isPiChatDrawerOpen: boolean;
// computed fn
geUserThreads: () => TUserThreads[];
geUserThreadsByWorkspaceId: (workspaceId: string) => TUserThreads[];
geUserThreadsByWorkspaceId: (workspaceId: string | undefined) => TUserThreads[];
geFavoriteChats: () => TUserThreads[];
getChatById: (chatId: string) => TChatHistory;
// actions
initPiChat: (chatId?: string) => void;
fetchChatById: (chatId: string) => void;
getAnswer: (chatId: string, query: string, focus: TFocus, isProjectChat: boolean) => Promise<string | undefined>;
getTemplates: () => Promise<TTemplate[]>;
fetchUserThreads: (workspaceId: string, isProjectChat: boolean) => void;
fetchChatById: (chatId: string, workspaceId: string | undefined) => void;
getAnswer: (
chatId: string,
query: string,
focus: TFocus,
isProjectChat: boolean,
workspaceSlug: string,
workspaceId: string | undefined
) => Promise<string | undefined>;
getTemplates: (workspaceId: string | undefined) => Promise<TTemplate[]>;
fetchUserThreads: (workspaceId: string | undefined, isProjectChat: boolean) => void;
searchCallback: (workspace: string, query: string, focus: TFocus) => Promise<IFormattedValue>;
sendFeedback: (chatId: string, message_index: number, feedback: EFeedback, feedbackMessage?: string) => Promise<void>;
fetchModels: () => Promise<void>;
sendFeedback: (
chatId: string,
message_index: number,
feedback: EFeedback,
workspaceId?: string,
feedbackMessage?: string
) => Promise<void>;
fetchModels: (workspaceId?: string) => Promise<void>;
setActiveModel: (model: TAiModels) => void;
createNewChat: (focus: TFocus, isProjectChat: boolean, workspaceId: string) => Promise<string>;
renameChat: (chatId: string, title: string) => Promise<void>;
createNewChat: (focus: TFocus, isProjectChat: boolean, workspaceId: string | undefined) => Promise<string>;
renameChat: (chatId: string, title: string, workspaceId: string | undefined) => Promise<void>;
deleteChat: (chatId: string, workspaceSlug: string) => Promise<void>;
favoriteChat: (chatId: string) => Promise<void>;
unfavoriteChat: (chatId: string) => Promise<void>;
fetchRecentChats: (isProjectChat: boolean) => Promise<void>;
fetchFavoriteChats: (workspaceId: string) => Promise<void>;
favoriteChat: (chatId: string, workspaceId: string | undefined) => Promise<void>;
unfavoriteChat: (chatId: string, workspaceId: string | undefined) => Promise<void>;
fetchRecentChats: (workspaceId: string | undefined, isProjectChat: boolean) => Promise<void>;
fetchFavoriteChats: (workspaceId: string | undefined) => Promise<void>;
togglePiChatDrawer: (value?: boolean) => void;
}
@@ -158,7 +171,7 @@ export class PiChatStore implements IPiChatStore {
// computed
geUserThreads = computedFn(() => this.piThreads.map((chatId) => this.chatMap[chatId]) || []);
geUserThreadsByWorkspaceId = computedFn((workspaceId: string) => {
geUserThreadsByWorkspaceId = computedFn((workspaceId: string | undefined) => {
if (!workspaceId) return [];
return (
this.projectThreads
@@ -186,7 +199,7 @@ export class PiChatStore implements IPiChatStore {
this.isAuthorized = true;
};
createNewChat = async (focus: TFocus, isProjectChat: boolean = false, workspaceId: string) => {
createNewChat = async (focus: TFocus, isProjectChat: boolean = false, workspaceId: string | undefined) => {
this.isNewChat = true;
let payload: TInitPayload = {
workspace_in_context: focus.isInWorkspaceContext,
@@ -216,8 +229,8 @@ export class PiChatStore implements IPiChatStore {
return newChatId;
};
getTemplates = async () => {
const response = await this.piChatService.listTemplates();
getTemplates = async (workspaceId: string | undefined) => {
const response = await this.piChatService.listTemplates(workspaceId);
return response?.templates;
};
@@ -225,6 +238,7 @@ export class PiChatStore implements IPiChatStore {
isNewChat: boolean,
chatId: string,
payload: TQuery,
workspaceId: string | undefined,
callback: (property: "answer" | "reasoning", value: string) => void
) => {
const token = await this.piChatService.retrieveToken(payload);
@@ -263,7 +277,7 @@ export class PiChatStore implements IPiChatStore {
this.isPiTypingMap[chatId] = false;
// Call the title api if its a new chat
if (isNewChat) {
const title = await this.piChatService.retrieveTitle(chatId);
const title = await this.piChatService.retrieveTitle(chatId, workspaceId);
runInAction(() => {
this.isNewChat = false;
update(this.chatMap, chatId, (chat) => ({
@@ -281,7 +295,14 @@ export class PiChatStore implements IPiChatStore {
};
};
getAnswer = async (chatId: string, query: string, focus: TFocus, isProjectChat: boolean = false) => {
getAnswer = async (
chatId: string,
query: string,
focus: TFocus,
isProjectChat: boolean = false,
workspaceSlug: string,
workspaceId: string | undefined
) => {
if (!chatId) {
throw new Error("Chat not initialized");
}
@@ -333,13 +354,15 @@ export class PiChatStore implements IPiChatStore {
}
: {},
is_project_chat: isProjectChat,
workspace_slug: workspaceSlug,
workspace_id: workspaceId,
};
if (focus.isInWorkspaceContext) {
payload = { ...payload, [focus.entityType]: focus.entityIdentifier };
}
// Api call here
this.getStreamingAnswer(isNewChat, chatId, payload, (property, value) => {
this.getStreamingAnswer(isNewChat, chatId, payload, workspaceId, (property, value) => {
newDialogue[property] += value;
runInAction(() => {
update(this.chatMap, chatId, (chat) => ({
@@ -364,14 +387,14 @@ export class PiChatStore implements IPiChatStore {
}
};
fetchChatById = async (chatId: string) => {
fetchChatById = async (chatId: string, workspaceId: string | undefined) => {
if (this.isNewChat) return;
try {
// Call api here
runInAction(() => {
this.isLoadingMap[chatId] = true;
});
const response = await this.piChatService.retrieveChat(chatId);
const response = await this.piChatService.retrieveChat(chatId, workspaceId);
runInAction(() => {
update(this.chatMap, chatId, (chat) => ({
...chat,
@@ -391,7 +414,7 @@ export class PiChatStore implements IPiChatStore {
}
};
fetchUserThreads = async (workspaceId: string, isProjectChat: boolean = false) => {
fetchUserThreads = async (workspaceId: string | undefined, isProjectChat: boolean = false) => {
const threads = isProjectChat ? this.projectThreads : this.piThreads;
try {
runInAction(() => {
@@ -419,13 +442,13 @@ export class PiChatStore implements IPiChatStore {
}
};
fetchRecentChats = async (isProjectChat: boolean = false) => {
fetchRecentChats = async (workspaceId: string | undefined, isProjectChat: boolean = false) => {
try {
const threads = isProjectChat ? this.projectThreads : this.piThreads;
runInAction(() => {
this.isLoadingThreads = true;
});
const response = await this.piChatService.listRecentChats();
const response = await this.piChatService.listRecentChats(workspaceId);
runInAction(() => {
response.results.forEach((chat) => {
update(this.chatMap, chat.chat_id, (prev) => ({
@@ -446,9 +469,9 @@ export class PiChatStore implements IPiChatStore {
}
};
fetchModels = async () => {
fetchModels = async (workspaceId: string | undefined) => {
try {
const response = await this.piChatService.listAiModels();
const response = await this.piChatService.listAiModels(workspaceId);
runInAction(() => {
this.models = response.models;
response.models.forEach((model) => {
@@ -476,7 +499,13 @@ export class PiChatStore implements IPiChatStore {
return response.results;
};
sendFeedback = async (chatId: string, message_index: number, feedback: EFeedback, feedbackMessage?: string) => {
sendFeedback = async (
chatId: string,
message_index: number,
feedback: EFeedback,
workspaceId?: string,
feedbackMessage?: string
) => {
const initialState = this.chatMap[chatId]?.dialogue?.[message_index]?.feedback;
runInAction(() => {
runInAction(() => {
@@ -491,6 +520,7 @@ export class PiChatStore implements IPiChatStore {
chat_id: chatId,
feedback,
feedback_message: feedbackMessage,
...(workspaceId && { workspace_id: workspaceId }),
});
return response;
} catch (e) {
@@ -503,7 +533,7 @@ export class PiChatStore implements IPiChatStore {
}
};
fetchFavoriteChats = async (workspaceId: string) => {
fetchFavoriteChats = async (workspaceId: string | undefined) => {
this.isLoadingFavoriteChats = true;
const response = await this.piChatService.listFavoriteChats(workspaceId);
runInAction(() => {
@@ -520,7 +550,7 @@ export class PiChatStore implements IPiChatStore {
});
};
favoriteChat = async (chatId: string) => {
favoriteChat = async (chatId: string, workspaceId: string | undefined) => {
const favoriteChats = this.favoriteChats;
try {
runInAction(() => {
@@ -530,7 +560,7 @@ export class PiChatStore implements IPiChatStore {
}));
this.favoriteChats = [...this.favoriteChats, chatId];
});
await this.piChatService.favoriteChat(chatId);
await this.piChatService.favoriteChat(chatId, workspaceId);
} catch (e) {
runInAction(() => {
update(this.chatMap, chatId, (chat) => ({
@@ -542,7 +572,7 @@ export class PiChatStore implements IPiChatStore {
}
};
unfavoriteChat = async (chatId: string) => {
unfavoriteChat = async (chatId: string, workspaceId: string | undefined) => {
const favoriteChats = this.favoriteChats;
try {
runInAction(() => {
@@ -552,7 +582,7 @@ export class PiChatStore implements IPiChatStore {
}));
this.favoriteChats = favoriteChats.filter((id) => id !== chatId);
});
await this.piChatService.unfavoriteChat(chatId);
await this.piChatService.unfavoriteChat(chatId, workspaceId);
} catch (e) {
runInAction(() => {
update(this.chatMap, chatId, (chat) => ({
@@ -564,7 +594,7 @@ export class PiChatStore implements IPiChatStore {
}
};
renameChat = async (chatId: string, title: string) => {
renameChat = async (chatId: string, title: string, workspaceId: string | undefined) => {
const initialState = this.chatMap[chatId]?.title;
try {
runInAction(() => {
@@ -573,7 +603,7 @@ export class PiChatStore implements IPiChatStore {
title,
}));
});
await this.piChatService.renameChat(chatId, title);
await this.piChatService.renameChat(chatId, title, workspaceId);
} catch (e) {
runInAction(() => {
update(this.chatMap, chatId, (chat) => ({
+6 -1
View File
@@ -25,8 +25,12 @@ export type TQuery = {
[key: string]: string;
};
is_project_chat?: boolean;
workspace_slug?: string;
};
export type TInitPayload = Pick<TQuery, "workspace_in_context" | "workspace_id" | "project_id" | "is_project_chat">;
export type TInitPayload = Pick<
TQuery,
"workspace_in_context" | "workspace_id" | "project_id" | "is_project_chat" | "workspace_slug"
>;
export type TSearchQuery = {
query: string;
};
@@ -36,6 +40,7 @@ export type TFeedback = {
message_index: number;
feedback: EFeedback;
feedback_message?: string;
workspace_id?: string;
};
export type TFocus = {