Feat: New agent from templates (#1117)
* upgrade deps * fix error after delete agent & chats * fix warning * new agent from template * improve select template * chat agent description optional * refactor * may update templates from remote
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
"markdown-it-sub": "^2.0.0",
|
||||
"markdown-it-sup": "^2.0.0",
|
||||
"mermaid": "^11.3.0",
|
||||
"sass": "^1.79.4",
|
||||
"sass": "^1.79.5",
|
||||
"vitepress": "^1.4.0",
|
||||
"vitepress-plugin-mermaid": "^2.0.17",
|
||||
"vue": "^3.5.11"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.47",
|
||||
"sass": "^1.79.4",
|
||||
"sass": "^1.79.5",
|
||||
"tailwindcss": "^3.4.13"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
"@electron-forge/publisher-s3": "^7.5.0",
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@langchain/community": "^0.3.4",
|
||||
"@langchain/core": "^0.3.8",
|
||||
"@langchain/core": "^0.3.9",
|
||||
"@langchain/ollama": "^0.1.0",
|
||||
"@mozilla/readability": "^0.5.0",
|
||||
"@radix-ui/react-accordion": "^1.2.1",
|
||||
@@ -134,13 +134,13 @@
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.0.0",
|
||||
"command-exists": "^1.2.9",
|
||||
"compromise": "^14.14.1",
|
||||
"compromise": "^14.14.2",
|
||||
"compromise-paragraphs": "^0.1.0",
|
||||
"compromise-stats": "^0.1.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"decamelize": "^6.0.0",
|
||||
"decamelize-keys": "^2.0.1",
|
||||
"echogarden": "^1.7.0",
|
||||
"echogarden": "^1.8.1",
|
||||
"electron-context-menu": "^4.0.4",
|
||||
"electron-log": "^5.2.0",
|
||||
"electron-settings": "^4.0.4",
|
||||
|
||||
69
enjoy/src/constants/chat-agent-templates.ts
Normal file
69
enjoy/src/constants/chat-agent-templates.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
export const CHAT_AGENT_TEMPLATES = [
|
||||
{
|
||||
key: "english-coach",
|
||||
name: "英语教练",
|
||||
description: "生成地道的美式英语,纽约腔调。",
|
||||
prompt: `你是我的英语教练。
|
||||
请将我的话改写成英文。
|
||||
不需要逐字翻译。
|
||||
请分析清楚我的内容,而后用英文重新逻辑清晰地组织它。
|
||||
请使用地道的美式英语,纽约腔调。
|
||||
请尽量使用日常词汇,尽量优先使用短语动词或者习惯用语。
|
||||
每个句子最长不应该超过 20 个单词。`,
|
||||
},
|
||||
{
|
||||
key: "ny-speak-easy",
|
||||
name: "NY Speak Easy",
|
||||
description: "",
|
||||
prompt: `Your role is to serves as an English spoken adviser, specializing in translating the user's words into everyday spoken English with a New York twist, focusing on common phrasal verbs and idioms. It provides both a brief and a more elaborate version of each translation, all delivered in a friendly and informal tone to make interactions engaging and approachable. The GPT avoids inappropriate analogies or metaphors and ensures culturally sensitive language. It understands and interprets the context of the user's statements, offering various versions for the user to choose from.`,
|
||||
},
|
||||
{
|
||||
key: "translation-hands",
|
||||
name: "Translation Hands",
|
||||
description: "",
|
||||
prompt:
|
||||
"Your role is to be an English guru, an expert in authentic American English, who assists users in expressing their thoughts clearly and fluently. You are not just translating words; you are delving into the essence of the user's message and reconstructing it in a way that maintains logical clarity and coherence. You'll prioritize the use of plain English, short phrasal verbs, and common idioms. It's important to craft sentences with varied lengths to create a natural rhythm and flow, making the language sound smooth and engaging. Avoid regional expressions or idioms that are too unique or restricted to specific areas. Your goal is to make American English accessible and appealing to a broad audience, helping users communicate effectively in a style that resonates with a wide range of English speakers.",
|
||||
},
|
||||
{
|
||||
key: "metaphor-pro",
|
||||
name: "Metaphor Pro",
|
||||
description: "",
|
||||
prompt: `Your primary role is to act as a 'Metaphor Guru.' It will specialize in analyzing content in various languages, identifying metaphors that might not be easily understood in English culture, and then providing suitable alternatives and explanations in English. This GPT should be adept at language translation and cultural interpretation, ensuring accurate and contextually appropriate metaphor translations. It should be careful to maintain the original sentiment and meaning of the metaphors while adapting them for an English-speaking audience. The GPT should ask for clarification if the provided content is too vague or lacks context. In terms of personalization, it should maintain a helpful and informative demeanor, focusing on delivering clear and concise explanations.`,
|
||||
},
|
||||
{
|
||||
key: "style-guru",
|
||||
name: "Style Guru",
|
||||
description: "",
|
||||
prompt: `Your primary role is to act as an English language guru, analyzing content provided by the user and offering detailed, formal suggestions to improve it, based on Joseph M. Williams' book, "Style: Toward Clarity and Grace." When users provide text, analyze it thoroughly for style, structure, and clarity, offering specific and detailed advice. Your feedback should be comprehensive and formal, providing in-depth explanations for each suggestion. Maintain a formal and academic tone in your interactions. If the meaning of a user's text is unclear, ask for clarification to ensure the advice provided is as accurate and helpful as possible. Treat each interaction independently, without referencing past interactions or writing styles, focusing solely on the text presented at the moment.`,
|
||||
},
|
||||
{
|
||||
key: "story-scout",
|
||||
name: "Story Scout",
|
||||
description: "",
|
||||
prompt: `You are a Story Searcher GPT, adept at searching through a vast knowledge base to find true stories that suit the user's content needs. Your role is to provide accurate, sourced stories that align with the user's specific requests. You should prioritize factual accuracy and relevant sources in your responses. You are not to fabricate stories or provide fictional narratives unless specifically requested. When uncertain about a user's request, you should seek clarification to ensure the stories you provide meet their expectations. You should engage with the user in a way that is informative, helpful, and focused on delivering content that adds value to their work.`,
|
||||
},
|
||||
{
|
||||
key: "research-aid",
|
||||
name: "Research Aid",
|
||||
description: "",
|
||||
prompt: `Your role is to act as a research aid, specifically designed to help users find the most interesting and recent scientific papers related to their topics of interest. You should provide DOI links to these papers for easy access. When a user presents a topic, you'll use your research abilities to find relevant, up-to-date scientific literature, focusing on providing accurate and helpful information. It's important to ensure that the information is recent and from credible scientific sources. If clarification is needed on the user's topic, you should ask for more details to refine the search. Your responses should be tailored to each user's inquiry, ensuring they are relevant and specific to the topic provided.`,
|
||||
},
|
||||
{
|
||||
key: "rhyme-master",
|
||||
name: "Rhyme Master",
|
||||
description: "",
|
||||
prompt: `Your role is to act as an English language guru, specializing in helping users craft rhyming sentences or phrases. You'll analyze the content provided by the user and suggest adjacent sentences or phrases that rhyme, adding a creative twist to their speech. Your goal is to enhance the user's speech or writing with rhythmic and rhyming elements, making it more engaging and stylish. You should prioritize understanding the context and maintaining the original message's integrity while introducing rhymes. If a user's input is unclear or lacks sufficient context for rhyming, you may politely ask for clarification. However, your primary approach should be to confidently create rhymes based on the given information, using your expertise in the English language. You should maintain a friendly and supportive tone, encouraging users in their creative writing endeavors.`,
|
||||
},
|
||||
{
|
||||
key: "quote-finder",
|
||||
name: "Quote Finder",
|
||||
description: "",
|
||||
prompt: `Your role is to assist users in finding famous quotations from English history, books, or literature that relate to their provided content or input. You should focus on understanding the user's request, identifying relevant themes or keywords, and then sourcing appropriate quotations from a wide range of historical and literary sources. You are expected to provide accurate and contextually relevant quotes, ensuring they align with the user's request. You should avoid providing incorrect or irrelevant quotations, and maintain a respectful and informative tone throughout the interaction. In cases where the request is unclear, you should seek clarification to better understand and fulfill the user's needs. Your responses should be personalized to each user's request, demonstrating an understanding of their specific inquiry and providing tailored quotations that best match their input.`,
|
||||
},
|
||||
{
|
||||
key: "analogy-finder",
|
||||
name: "Analogy Finder",
|
||||
description: "",
|
||||
prompt: `Your role is to be a language guru, specializing in providing analogies. When a user provides words, phrases, or passages, you'll search your extensive knowledge base to offer several fitting analogies to enhance their expression. It's important to focus on relevance and creativity in your analogies to ensure they truly enrich the user's language. Avoid providing generic or unrelated analogies. If a passage is unclear or too broad, ask for clarification to ensure the analogies are as fitting as possible.`,
|
||||
},
|
||||
];
|
||||
@@ -235,4 +235,4 @@ export const GPT_PRESETS = [
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./chat-agent-templates";
|
||||
export * from "./gpt-presets";
|
||||
export * from "./ipa";
|
||||
|
||||
|
||||
@@ -865,5 +865,6 @@
|
||||
"added": "Added",
|
||||
"migrateToChat": "Migrate to chat",
|
||||
"memberJoined": "{{name}} has joined the chat.",
|
||||
"memberLeft": "{{name}} has left the chat."
|
||||
"memberLeft": "{{name}} has left the chat.",
|
||||
"templates": "templates"
|
||||
}
|
||||
|
||||
@@ -865,5 +865,6 @@
|
||||
"added": "已添加",
|
||||
"migrateToChat": "迁移到聊天",
|
||||
"memberJoined": "{{name}} 已加入聊天",
|
||||
"memberLeft": "{{name}} 已离开聊天"
|
||||
"memberLeft": "{{name}} 已离开聊天",
|
||||
"templates": "模板"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,12 @@ import { z } from "zod";
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Command,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
@@ -12,6 +18,9 @@ import {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
Input,
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
@@ -26,20 +35,42 @@ import {
|
||||
AISettingsProviderContext,
|
||||
AppSettingsProviderContext,
|
||||
} from "@renderer/context";
|
||||
import { useContext } from "react";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { ChatAgentTypeEnum } from "@/types/enums";
|
||||
|
||||
import { CHAT_AGENT_TEMPLATES } from "@/constants";
|
||||
import { cn } from "@/renderer/lib/utils";
|
||||
import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons";
|
||||
export const ChatAgentForm = (props: {
|
||||
agent?: ChatAgentType;
|
||||
onFinish: () => void;
|
||||
}) => {
|
||||
const { agent, onFinish } = props;
|
||||
const { EnjoyApp, learningLanguage } = useContext(AppSettingsProviderContext);
|
||||
const { EnjoyApp, learningLanguage, webApi } = useContext(
|
||||
AppSettingsProviderContext
|
||||
);
|
||||
const { currentTtsEngine } = useContext(AISettingsProviderContext);
|
||||
const [selectedTemplate, setSelectedTemplate] = useState<string>("custom");
|
||||
const [templates, setTemplates] = useState<
|
||||
{
|
||||
key: string;
|
||||
name: string;
|
||||
description: string;
|
||||
prompt: string;
|
||||
}[]
|
||||
>(CHAT_AGENT_TEMPLATES);
|
||||
|
||||
const fetchTemplates = () => {
|
||||
webApi.config("chat_agent_templates").then((tpls) => {
|
||||
if (Array.isArray(tpls) && tpls.length > 0) {
|
||||
setTemplates(tpls);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const agentFormSchema = z.object({
|
||||
type: z.enum([ChatAgentTypeEnum.GPT, ChatAgentTypeEnum.TTS]),
|
||||
name: z.string().min(1),
|
||||
description: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
config: z.object({
|
||||
prompt: z.string().optional(),
|
||||
tts: z
|
||||
@@ -108,6 +139,45 @@ export const ChatAgentForm = (props: {
|
||||
}
|
||||
});
|
||||
|
||||
const TEMPLATES = [
|
||||
{
|
||||
key: "custom",
|
||||
name: t("custom"),
|
||||
description: "",
|
||||
prompt: "",
|
||||
},
|
||||
{
|
||||
key: "default",
|
||||
name: t("models.chatAgent.namePlaceholder"),
|
||||
description: t("models.chatAgent.descriptionPlaceholder"),
|
||||
prompt: t("models.chatAgent.promptPlaceholder"),
|
||||
},
|
||||
...templates,
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
if (form.watch("type") !== ChatAgentTypeEnum.GPT) {
|
||||
form.setValue("name", "");
|
||||
form.setValue("config.prompt", "");
|
||||
} else {
|
||||
const template = TEMPLATES.find((p) => p.key === selectedTemplate);
|
||||
if (!template) return;
|
||||
|
||||
if (selectedTemplate === "custom") {
|
||||
form.setValue("name", "");
|
||||
form.setValue("description", "");
|
||||
} else {
|
||||
form.setValue("name", template.name || "");
|
||||
form.setValue("description", template.description || "");
|
||||
}
|
||||
form.setValue("config.prompt", template.prompt || "");
|
||||
}
|
||||
}, [selectedTemplate, form.watch("type")]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTemplates();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={onSubmit}>
|
||||
@@ -165,6 +235,62 @@ export const ChatAgentForm = (props: {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{form.watch("type") === ChatAgentTypeEnum.GPT && (
|
||||
<FormItem className="flex flex-col">
|
||||
<FormLabel className="capitalize">{t("templates")}</FormLabel>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
className={cn(
|
||||
"w-full justify-between",
|
||||
!selectedTemplate && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{selectedTemplate
|
||||
? TEMPLATES.find(
|
||||
(template) => template.key === selectedTemplate
|
||||
)?.name
|
||||
: t("templates")}
|
||||
<CaretSortIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-full p-0">
|
||||
<Command>
|
||||
<CommandInput
|
||||
placeholder={t("templates")}
|
||||
className="h-9"
|
||||
/>
|
||||
<CommandList>
|
||||
<CommandEmpty>{t("noTemplatesFound")}</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{TEMPLATES.map((template) => (
|
||||
<CommandItem
|
||||
key={template.key}
|
||||
value={template.key}
|
||||
onSelect={() => setSelectedTemplate(template.key)}
|
||||
>
|
||||
{template.name}
|
||||
<CheckIcon
|
||||
className={cn(
|
||||
"ml-auto h-4 w-4",
|
||||
template.key === selectedTemplate
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
|
||||
@@ -58,8 +58,6 @@ export const ChatAgentMessage = (props: {
|
||||
);
|
||||
const [displayPlayer, setDisplayPlayer] = useState(false);
|
||||
|
||||
const chatMember = chatMembers.find((m) => m.id === chatMessage.member.id);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
ref.current.scrollIntoView({ behavior: "smooth" });
|
||||
@@ -72,6 +70,8 @@ export const ChatAgentMessage = (props: {
|
||||
}
|
||||
}, [chatMessage]);
|
||||
|
||||
if (!chatMessage) return;
|
||||
const chatMember = chatMembers.find((m) => m?.id === chatMessage.member?.id);
|
||||
if (!chatMember?.agent) return;
|
||||
|
||||
return (
|
||||
@@ -174,7 +174,7 @@ const ChatAgentMessageActions = (props: {
|
||||
setTranslation,
|
||||
autoSpeech,
|
||||
} = props;
|
||||
const { chat, setShadowing, onDeleteMessage } = useContext(
|
||||
const { chat, setShadowing, deleteMessage } = useContext(
|
||||
ChatSessionProviderContext
|
||||
);
|
||||
const { EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
@@ -417,7 +417,7 @@ const ChatAgentMessageActions = (props: {
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => onDeleteMessage(chatMessage.id)}
|
||||
onClick={() => deleteMessage(chatMessage.id)}
|
||||
>
|
||||
<span className="mr-auto text-destructive capitalize">
|
||||
{t("delete")}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogTitle,
|
||||
Input,
|
||||
toast,
|
||||
@@ -128,7 +129,10 @@ export const ChatAgents = (props: {
|
||||
onOpenChange={() => setEditingChatAgent(null)}
|
||||
>
|
||||
<DialogContent className="max-w-screen-md max-h-full overflow-auto">
|
||||
<DialogTitle className="sr-only"></DialogTitle>
|
||||
<DialogTitle className="sr-only">Edit Chat Agent</DialogTitle>
|
||||
<DialogDescription className="sr-only">
|
||||
Edit chat agent configuration
|
||||
</DialogDescription>
|
||||
<ChatAgentForm
|
||||
agent={editingChatAgent}
|
||||
onFinish={() => setEditingChatAgent(null)}
|
||||
@@ -137,7 +141,10 @@ export const ChatAgents = (props: {
|
||||
</Dialog>
|
||||
<Dialog open={creatingChatAgent} onOpenChange={setCreatingChatAgent}>
|
||||
<DialogContent className="max-w-screen-md max-h-full overflow-auto">
|
||||
<DialogTitle className="sr-only"></DialogTitle>
|
||||
<DialogTitle className="sr-only">Create Chat Agent</DialogTitle>
|
||||
<DialogDescription className="sr-only">
|
||||
Create a new chat agent
|
||||
</DialogDescription>
|
||||
<ChatAgentForm
|
||||
agent={null}
|
||||
onFinish={() => setCreatingChatAgent(false)}
|
||||
|
||||
@@ -37,7 +37,7 @@ export const ChatInput = () => {
|
||||
recordingTime,
|
||||
isPaused,
|
||||
askAgent,
|
||||
onCreateMessage,
|
||||
createMessage,
|
||||
shadowing,
|
||||
} = useContext(ChatSessionProviderContext);
|
||||
const { EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
@@ -67,6 +67,16 @@ export const ChatInput = () => {
|
||||
};
|
||||
}, [inputRef.current]);
|
||||
|
||||
useEffect(() => {
|
||||
if (content) return;
|
||||
|
||||
const evt = new CustomEvent("autosize:update", {
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
});
|
||||
inputRef.current?.dispatchEvent(evt);
|
||||
}, [content]);
|
||||
|
||||
useEffect(() => {
|
||||
EnjoyApp.cacheObjects
|
||||
.get(`chat-input-mode-${chat.id}`)
|
||||
@@ -199,7 +209,9 @@ export const ChatInput = () => {
|
||||
data-tooltip-id={`${chat.id}-tooltip`}
|
||||
data-tooltip-content={t("send")}
|
||||
onClick={() =>
|
||||
onCreateMessage(content, { onSuccess: () => setContent("") })
|
||||
createMessage(content, {
|
||||
onSuccess: () => setContent(""),
|
||||
})
|
||||
}
|
||||
disabled={submitting || !content}
|
||||
className="rounded-full shadow w-8 h-8"
|
||||
|
||||
@@ -43,6 +43,7 @@ export const ChatList = (props: {
|
||||
if (!chatAgent) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnjoyApp.chats
|
||||
.create({
|
||||
name: t("newChat"),
|
||||
@@ -105,6 +106,11 @@ export const ChatList = (props: {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!chatAgent) {
|
||||
setCurrentChat(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentAgentNotInvolved =
|
||||
currentChat?.members?.findIndex(
|
||||
(member) => member.userId === chatAgent?.id
|
||||
@@ -117,7 +123,7 @@ export const ChatList = (props: {
|
||||
if (chat) {
|
||||
setCurrentChat(chat);
|
||||
} else {
|
||||
handleCreateChat();
|
||||
setCurrentChat(null);
|
||||
}
|
||||
}
|
||||
}, [chats, chatAgent]);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ChatSuggestionButton = (props: {
|
||||
children?: ReactElement;
|
||||
}) => {
|
||||
const { chat } = props;
|
||||
const { chatMessages, onCreateMessage } = useContext(
|
||||
const { chatMessages, createMessage } = useContext(
|
||||
ChatSessionProviderContext
|
||||
);
|
||||
const [suggestions, setSuggestions] = useState<
|
||||
@@ -138,7 +138,7 @@ export const ChatSuggestionButton = (props: {
|
||||
size="icon"
|
||||
className="rounded-full w-6 h-6"
|
||||
onClick={() =>
|
||||
onCreateMessage(suggestion.text, {
|
||||
createMessage(suggestion.text, {
|
||||
onSuccess: () => setOpen(false),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ export const ChatUserMessage = (props: {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [editing, setEditing] = useState<boolean>(false);
|
||||
const [content, setContent] = useState<string>(chatMessage.content);
|
||||
const { onUpdateMessage, askAgent, submitting, asking } = useContext(
|
||||
const { updateMessage, askAgent, submitting, asking } = useContext(
|
||||
ChatSessionProviderContext
|
||||
);
|
||||
const [displayPlayer, setDisplayPlayer] = useState(false);
|
||||
@@ -130,7 +130,7 @@ export const ChatUserMessage = (props: {
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
onUpdateMessage(chatMessage.id, { content }).finally(() =>
|
||||
updateMessage(chatMessage.id, { content }).finally(() =>
|
||||
setEditing(false)
|
||||
)
|
||||
}
|
||||
@@ -204,7 +204,7 @@ const ChatUserMessageActions = (props: {
|
||||
isPaused,
|
||||
assessing,
|
||||
setAssessing,
|
||||
onDeleteMessage,
|
||||
deleteMessage,
|
||||
submitting,
|
||||
} = useContext(ChatSessionProviderContext);
|
||||
|
||||
@@ -384,7 +384,7 @@ const ChatUserMessageActions = (props: {
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
className="cursor-pointer"
|
||||
onClick={() => onDeleteMessage(chatMessage.id)}
|
||||
onClick={() => deleteMessage(chatMessage.id)}
|
||||
>
|
||||
<span className="mr-auto text-destructive capitalize">
|
||||
{t("delete")}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import * as React from "react";
|
||||
import { type DialogProps } from "@radix-ui/react-dialog";
|
||||
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
||||
import { Command as CommandPrimitive } from "cmdk";
|
||||
import { Search } from "lucide-react";
|
||||
|
||||
import { cn } from "@renderer/lib/utils";
|
||||
import { Dialog, DialogContent } from "@renderer/components/ui/dialog";
|
||||
@@ -28,7 +28,7 @@ interface CommandDialogProps extends DialogProps {}
|
||||
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
|
||||
return (
|
||||
<Dialog {...props}>
|
||||
<DialogContent className="overflow-hidden p-0 shadow-lg">
|
||||
<DialogContent className="overflow-hidden p-0">
|
||||
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||
{children}
|
||||
</Command>
|
||||
@@ -42,11 +42,11 @@ const CommandInput = React.forwardRef<
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
||||
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<MagnifyingGlassIcon className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<CommandPrimitive.Input
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -117,7 +117,7 @@ const CommandItem = React.forwardRef<
|
||||
<CommandPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -53,15 +53,15 @@ type ChatSessionProviderState = {
|
||||
setShadowing: (audio: AudioType) => void;
|
||||
assessing: RecordingType;
|
||||
setAssessing: (recording: RecordingType) => void;
|
||||
onDeleteMessage?: (id: string) => void;
|
||||
onCreateMessage?: (
|
||||
deleteMessage?: (id: string) => void;
|
||||
createMessage?: (
|
||||
content: string,
|
||||
options: {
|
||||
onSuccess?: (message: ChatMessageType) => void;
|
||||
onError?: (error: Error) => void;
|
||||
}
|
||||
) => Promise<ChatMessageType | void>;
|
||||
onUpdateMessage?: (
|
||||
updateMessage?: (
|
||||
id: string,
|
||||
data: Partial<ChatMessageType>
|
||||
) => Promise<ChatMessageType>;
|
||||
@@ -89,8 +89,8 @@ const initialState: ChatSessionProviderState = {
|
||||
setShadowing: () => null,
|
||||
assessing: null,
|
||||
setAssessing: () => null,
|
||||
onCreateMessage: () => null,
|
||||
onUpdateMessage: () => null,
|
||||
createMessage: () => null,
|
||||
updateMessage: () => null,
|
||||
};
|
||||
|
||||
export const ChatSessionProviderContext =
|
||||
@@ -116,9 +116,9 @@ export const ChatSessionProvider = ({
|
||||
chatMembers,
|
||||
chatMessages,
|
||||
dispatchChatMessages,
|
||||
onCreateUserMessage,
|
||||
onUpdateMessage,
|
||||
onDeleteMessage,
|
||||
createUserMessage,
|
||||
updateMessage,
|
||||
deleteMessage,
|
||||
invokeAgent,
|
||||
} = useChatSession(chatId);
|
||||
|
||||
@@ -153,7 +153,7 @@ export const ChatSessionProvider = ({
|
||||
});
|
||||
};
|
||||
|
||||
const onCreateMessage = async (
|
||||
const createMessage = async (
|
||||
content: string,
|
||||
options: {
|
||||
onSuccess?: (message: ChatMessageType) => void;
|
||||
@@ -164,7 +164,7 @@ export const ChatSessionProvider = ({
|
||||
if (submitting) return;
|
||||
|
||||
setSubmitting(true);
|
||||
onCreateUserMessage(content)
|
||||
createUserMessage(content)
|
||||
.then((message) => {
|
||||
if (message) {
|
||||
onSuccess?.(message);
|
||||
@@ -201,12 +201,12 @@ export const ChatSessionProvider = ({
|
||||
});
|
||||
|
||||
if (pendingMessage) {
|
||||
await onUpdateMessage(pendingMessage.id, {
|
||||
await updateMessage(pendingMessage.id, {
|
||||
content: transcript,
|
||||
recordingUrl: url,
|
||||
});
|
||||
} else {
|
||||
await onCreateUserMessage(transcript, url);
|
||||
await createUserMessage(transcript, url);
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error(error.message);
|
||||
@@ -390,9 +390,9 @@ export const ChatSessionProvider = ({
|
||||
setShadowing,
|
||||
assessing,
|
||||
setAssessing,
|
||||
onDeleteMessage: (id) => setDeletingMessage(id),
|
||||
onCreateMessage,
|
||||
onUpdateMessage,
|
||||
deleteMessage: (id) => setDeletingMessage(id),
|
||||
createMessage,
|
||||
updateMessage,
|
||||
}}
|
||||
>
|
||||
<MediaShadowProvider>
|
||||
@@ -414,9 +414,7 @@ export const ChatSessionProvider = ({
|
||||
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>{t("cancel")}</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => onDeleteMessage(deletingMessage)}
|
||||
>
|
||||
<AlertDialogAction onClick={() => deleteMessage(deletingMessage)}>
|
||||
{t("confirm")}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
|
||||
@@ -56,7 +56,7 @@ export const useChatMessage = (chatId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const onCreateUserMessage = (content: string, recordingUrl?: string) => {
|
||||
const createUserMessage = (content: string, recordingUrl?: string) => {
|
||||
if (!content) return;
|
||||
|
||||
return EnjoyApp.chatMessages
|
||||
@@ -72,11 +72,11 @@ export const useChatMessage = (chatId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const onUpdateMessage = (id: string, data: ChatMessageDtoType) => {
|
||||
const updateMessage = (id: string, data: ChatMessageDtoType) => {
|
||||
return EnjoyApp.chatMessages.update(id, data);
|
||||
};
|
||||
|
||||
const onDeleteMessage = async (chatMessageId: string) => {
|
||||
const deleteMessage = async (chatMessageId: string) => {
|
||||
return EnjoyApp.chatMessages
|
||||
.destroy(chatMessageId)
|
||||
.then(() =>
|
||||
@@ -206,7 +206,7 @@ export const useChatMessage = (chatId: string) => {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
}
|
||||
onUpdateMessage(pendingMessage.id, {
|
||||
updateMessage(pendingMessage.id, {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
};
|
||||
@@ -265,7 +265,7 @@ export const useChatMessage = (chatId: string) => {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
if (pendingMessage) {
|
||||
onUpdateMessage(pendingMessage.id, {
|
||||
updateMessage(pendingMessage.id, {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
}
|
||||
@@ -287,7 +287,7 @@ export const useChatMessage = (chatId: string) => {
|
||||
content: pendingMessage.content,
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
onUpdateMessage(pendingMessage.id, {
|
||||
updateMessage(pendingMessage.id, {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
|
||||
@@ -378,9 +378,9 @@ export const useChatMessage = (chatId: string) => {
|
||||
chatMessages,
|
||||
fetchChatMessages,
|
||||
dispatchChatMessages,
|
||||
onCreateUserMessage,
|
||||
onUpdateMessage,
|
||||
onDeleteMessage,
|
||||
createUserMessage,
|
||||
updateMessage,
|
||||
deleteMessage,
|
||||
invokeAgent,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ export const useChatSession = (chatId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const onCreateUserMessage = (content: string, recordingUrl?: string) => {
|
||||
const createUserMessage = (content: string, recordingUrl?: string) => {
|
||||
if (!content) return;
|
||||
|
||||
return EnjoyApp.chatMessages
|
||||
@@ -72,11 +72,11 @@ export const useChatSession = (chatId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
const onUpdateMessage = (id: string, data: ChatMessageDtoType) => {
|
||||
const updateMessage = (id: string, data: ChatMessageDtoType) => {
|
||||
return EnjoyApp.chatMessages.update(id, data);
|
||||
};
|
||||
|
||||
const onDeleteMessage = async (chatMessageId: string) => {
|
||||
const deleteMessage = async (chatMessageId: string) => {
|
||||
return EnjoyApp.chatMessages
|
||||
.destroy(chatMessageId)
|
||||
.then(() =>
|
||||
@@ -228,7 +228,7 @@ export const useChatSession = (chatId: string) => {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
}
|
||||
onUpdateMessage(pendingMessage.id, {
|
||||
updateMessage(pendingMessage.id, {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
};
|
||||
@@ -287,7 +287,7 @@ export const useChatSession = (chatId: string) => {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
if (pendingMessage) {
|
||||
onUpdateMessage(pendingMessage.id, {
|
||||
updateMessage(pendingMessage.id, {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
}
|
||||
@@ -309,7 +309,7 @@ export const useChatSession = (chatId: string) => {
|
||||
content: pendingMessage.content,
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
onUpdateMessage(pendingMessage.id, {
|
||||
updateMessage(pendingMessage.id, {
|
||||
state: ChatMessageStateEnum.COMPLETED,
|
||||
});
|
||||
|
||||
@@ -400,9 +400,9 @@ export const useChatSession = (chatId: string) => {
|
||||
chatMessages,
|
||||
fetchChatMessages,
|
||||
dispatchChatMessages,
|
||||
onCreateUserMessage,
|
||||
onUpdateMessage,
|
||||
onDeleteMessage,
|
||||
createUserMessage,
|
||||
updateMessage,
|
||||
deleteMessage,
|
||||
invokeAgent,
|
||||
};
|
||||
};
|
||||
|
||||
335
yarn.lock
335
yarn.lock
@@ -17,7 +17,7 @@ __metadata:
|
||||
markdown-it-sub: "npm:^2.0.0"
|
||||
markdown-it-sup: "npm:^2.0.0"
|
||||
mermaid: "npm:^11.3.0"
|
||||
sass: "npm:^1.79.4"
|
||||
sass: "npm:^1.79.5"
|
||||
swiper: "npm:^11.1.14"
|
||||
vitepress: "npm:^1.4.0"
|
||||
vitepress-plugin-mermaid: "npm:^2.0.17"
|
||||
@@ -34,7 +34,7 @@ __metadata:
|
||||
nuxt: "npm:^3.13.2"
|
||||
nuxt-og-image: "npm:^3.0.4"
|
||||
postcss: "npm:^8.4.47"
|
||||
sass: "npm:^1.79.4"
|
||||
sass: "npm:^1.79.5"
|
||||
tailwindcss: "npm:^3.4.13"
|
||||
vue: "npm:^3.5.11"
|
||||
vue-router: "npm:^4.4.5"
|
||||
@@ -363,25 +363,25 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-polly@npm:^3.667.0":
|
||||
version: 3.668.0
|
||||
resolution: "@aws-sdk/client-polly@npm:3.668.0"
|
||||
"@aws-sdk/client-polly@npm:^3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/client-polly@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-crypto/sha256-browser": "npm:5.2.0"
|
||||
"@aws-crypto/sha256-js": "npm:5.2.0"
|
||||
"@aws-sdk/client-sso-oidc": "npm:3.668.0"
|
||||
"@aws-sdk/client-sts": "npm:3.668.0"
|
||||
"@aws-sdk/client-sso-oidc": "npm:3.669.0"
|
||||
"@aws-sdk/client-sts": "npm:3.669.0"
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-node": "npm:3.668.0"
|
||||
"@aws-sdk/credential-provider-node": "npm:3.669.0"
|
||||
"@aws-sdk/middleware-host-header": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-logger": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-recursion-detection": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.668.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.669.0"
|
||||
"@aws-sdk/region-config-resolver": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@aws-sdk/util-endpoints": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-browser": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.668.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.669.0"
|
||||
"@smithy/config-resolver": "npm:^3.0.9"
|
||||
"@smithy/core": "npm:^2.4.8"
|
||||
"@smithy/fetch-http-handler": "npm:^3.2.9"
|
||||
@@ -409,7 +409,7 @@ __metadata:
|
||||
"@smithy/util-stream": "npm:^3.1.9"
|
||||
"@smithy/util-utf8": "npm:^3.0.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/22c661ec189040ac2e09b1b79159ef364a77711b96ff908fa8aa14bdb8fa04236952f568802c2159d40549f516981f0cbde387374d40abce10bb68ad94714af8
|
||||
checksum: 10c0/0c8c4b0fe92bb0ae0a3e6a12c6fb1e7b8533ce7748ecbf020b3c48f17bf5e86fc927ee3b37b6ed5d79c2d8f43613db0e33a45c79b577fc578ff93a1bccc28aa0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -528,6 +528,55 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-sso-oidc@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/client-sso-oidc@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-crypto/sha256-browser": "npm:5.2.0"
|
||||
"@aws-crypto/sha256-js": "npm:5.2.0"
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-node": "npm:3.669.0"
|
||||
"@aws-sdk/middleware-host-header": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-logger": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-recursion-detection": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.669.0"
|
||||
"@aws-sdk/region-config-resolver": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@aws-sdk/util-endpoints": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-browser": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.669.0"
|
||||
"@smithy/config-resolver": "npm:^3.0.9"
|
||||
"@smithy/core": "npm:^2.4.8"
|
||||
"@smithy/fetch-http-handler": "npm:^3.2.9"
|
||||
"@smithy/hash-node": "npm:^3.0.7"
|
||||
"@smithy/invalid-dependency": "npm:^3.0.7"
|
||||
"@smithy/middleware-content-length": "npm:^3.0.9"
|
||||
"@smithy/middleware-endpoint": "npm:^3.1.4"
|
||||
"@smithy/middleware-retry": "npm:^3.0.23"
|
||||
"@smithy/middleware-serde": "npm:^3.0.7"
|
||||
"@smithy/middleware-stack": "npm:^3.0.7"
|
||||
"@smithy/node-config-provider": "npm:^3.1.8"
|
||||
"@smithy/node-http-handler": "npm:^3.2.4"
|
||||
"@smithy/protocol-http": "npm:^4.1.4"
|
||||
"@smithy/smithy-client": "npm:^3.4.0"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
"@smithy/url-parser": "npm:^3.0.7"
|
||||
"@smithy/util-base64": "npm:^3.0.0"
|
||||
"@smithy/util-body-length-browser": "npm:^3.0.0"
|
||||
"@smithy/util-body-length-node": "npm:^3.0.0"
|
||||
"@smithy/util-defaults-mode-browser": "npm:^3.0.23"
|
||||
"@smithy/util-defaults-mode-node": "npm:^3.0.23"
|
||||
"@smithy/util-endpoints": "npm:^2.1.3"
|
||||
"@smithy/util-middleware": "npm:^3.0.7"
|
||||
"@smithy/util-retry": "npm:^3.0.7"
|
||||
"@smithy/util-utf8": "npm:^3.0.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
peerDependencies:
|
||||
"@aws-sdk/client-sts": ^3.669.0
|
||||
checksum: 10c0/670936890e43435f532107ca73ede05d417e1078e522c77611cac33015571626e3865b7a46219d951e9de4e599b7a85ddadeb197e2923c8b20feb2d63985d1e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-sso@npm:3.668.0":
|
||||
version: 3.668.0
|
||||
resolution: "@aws-sdk/client-sso@npm:3.668.0"
|
||||
@@ -574,6 +623,52 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-sso@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/client-sso@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-crypto/sha256-browser": "npm:5.2.0"
|
||||
"@aws-crypto/sha256-js": "npm:5.2.0"
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-host-header": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-logger": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-recursion-detection": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.669.0"
|
||||
"@aws-sdk/region-config-resolver": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@aws-sdk/util-endpoints": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-browser": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.669.0"
|
||||
"@smithy/config-resolver": "npm:^3.0.9"
|
||||
"@smithy/core": "npm:^2.4.8"
|
||||
"@smithy/fetch-http-handler": "npm:^3.2.9"
|
||||
"@smithy/hash-node": "npm:^3.0.7"
|
||||
"@smithy/invalid-dependency": "npm:^3.0.7"
|
||||
"@smithy/middleware-content-length": "npm:^3.0.9"
|
||||
"@smithy/middleware-endpoint": "npm:^3.1.4"
|
||||
"@smithy/middleware-retry": "npm:^3.0.23"
|
||||
"@smithy/middleware-serde": "npm:^3.0.7"
|
||||
"@smithy/middleware-stack": "npm:^3.0.7"
|
||||
"@smithy/node-config-provider": "npm:^3.1.8"
|
||||
"@smithy/node-http-handler": "npm:^3.2.4"
|
||||
"@smithy/protocol-http": "npm:^4.1.4"
|
||||
"@smithy/smithy-client": "npm:^3.4.0"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
"@smithy/url-parser": "npm:^3.0.7"
|
||||
"@smithy/util-base64": "npm:^3.0.0"
|
||||
"@smithy/util-body-length-browser": "npm:^3.0.0"
|
||||
"@smithy/util-body-length-node": "npm:^3.0.0"
|
||||
"@smithy/util-defaults-mode-browser": "npm:^3.0.23"
|
||||
"@smithy/util-defaults-mode-node": "npm:^3.0.23"
|
||||
"@smithy/util-endpoints": "npm:^2.1.3"
|
||||
"@smithy/util-middleware": "npm:^3.0.7"
|
||||
"@smithy/util-retry": "npm:^3.0.7"
|
||||
"@smithy/util-utf8": "npm:^3.0.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/ef0e3a5d6a1e0f226a3f688dd99ab7283a40851d5aec1e81edbe9add7f68f8cf9d35f337c3d7486bc8526454ee7deb1c806681902e6e384965e431f38c8906e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-sts@npm:3.668.0":
|
||||
version: 3.668.0
|
||||
resolution: "@aws-sdk/client-sts@npm:3.668.0"
|
||||
@@ -622,29 +717,77 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-transcribe-streaming@npm:^3.667.0":
|
||||
version: 3.668.0
|
||||
resolution: "@aws-sdk/client-transcribe-streaming@npm:3.668.0"
|
||||
"@aws-sdk/client-sts@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/client-sts@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-crypto/sha256-browser": "npm:5.2.0"
|
||||
"@aws-crypto/sha256-js": "npm:5.2.0"
|
||||
"@aws-sdk/client-sso-oidc": "npm:3.668.0"
|
||||
"@aws-sdk/client-sts": "npm:3.668.0"
|
||||
"@aws-sdk/client-sso-oidc": "npm:3.669.0"
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-node": "npm:3.668.0"
|
||||
"@aws-sdk/credential-provider-node": "npm:3.669.0"
|
||||
"@aws-sdk/middleware-host-header": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-logger": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-recursion-detection": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.669.0"
|
||||
"@aws-sdk/region-config-resolver": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@aws-sdk/util-endpoints": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-browser": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.669.0"
|
||||
"@smithy/config-resolver": "npm:^3.0.9"
|
||||
"@smithy/core": "npm:^2.4.8"
|
||||
"@smithy/fetch-http-handler": "npm:^3.2.9"
|
||||
"@smithy/hash-node": "npm:^3.0.7"
|
||||
"@smithy/invalid-dependency": "npm:^3.0.7"
|
||||
"@smithy/middleware-content-length": "npm:^3.0.9"
|
||||
"@smithy/middleware-endpoint": "npm:^3.1.4"
|
||||
"@smithy/middleware-retry": "npm:^3.0.23"
|
||||
"@smithy/middleware-serde": "npm:^3.0.7"
|
||||
"@smithy/middleware-stack": "npm:^3.0.7"
|
||||
"@smithy/node-config-provider": "npm:^3.1.8"
|
||||
"@smithy/node-http-handler": "npm:^3.2.4"
|
||||
"@smithy/protocol-http": "npm:^4.1.4"
|
||||
"@smithy/smithy-client": "npm:^3.4.0"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
"@smithy/url-parser": "npm:^3.0.7"
|
||||
"@smithy/util-base64": "npm:^3.0.0"
|
||||
"@smithy/util-body-length-browser": "npm:^3.0.0"
|
||||
"@smithy/util-body-length-node": "npm:^3.0.0"
|
||||
"@smithy/util-defaults-mode-browser": "npm:^3.0.23"
|
||||
"@smithy/util-defaults-mode-node": "npm:^3.0.23"
|
||||
"@smithy/util-endpoints": "npm:^2.1.3"
|
||||
"@smithy/util-middleware": "npm:^3.0.7"
|
||||
"@smithy/util-retry": "npm:^3.0.7"
|
||||
"@smithy/util-utf8": "npm:^3.0.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/97867fe19911100be275079d427c9cae08af0f27612d679f62b751c54bb32d7e3a3c2ec7b8ab411d611f3545b566b4af7f20f8ca49e5d6747c4a2e3f81c03803
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/client-transcribe-streaming@npm:^3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/client-transcribe-streaming@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-crypto/sha256-browser": "npm:5.2.0"
|
||||
"@aws-crypto/sha256-js": "npm:5.2.0"
|
||||
"@aws-sdk/client-sso-oidc": "npm:3.669.0"
|
||||
"@aws-sdk/client-sts": "npm:3.669.0"
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-node": "npm:3.669.0"
|
||||
"@aws-sdk/eventstream-handler-node": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-eventstream": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-host-header": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-logger": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-recursion-detection": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-sdk-transcribe-streaming": "npm:3.667.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.668.0"
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.669.0"
|
||||
"@aws-sdk/middleware-websocket": "npm:3.667.0"
|
||||
"@aws-sdk/region-config-resolver": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@aws-sdk/util-endpoints": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-browser": "npm:3.667.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.668.0"
|
||||
"@aws-sdk/util-user-agent-node": "npm:3.669.0"
|
||||
"@smithy/config-resolver": "npm:^3.0.9"
|
||||
"@smithy/core": "npm:^2.4.8"
|
||||
"@smithy/eventstream-serde-browser": "npm:^3.0.10"
|
||||
@@ -674,7 +817,7 @@ __metadata:
|
||||
"@smithy/util-retry": "npm:^3.0.7"
|
||||
"@smithy/util-utf8": "npm:^3.0.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/1a475273544d39fb554efbbbe18f9e295caa29b70b6958bb4c2f30c9acd6faa1eb5651650cf870a19681ccf11cf7c9718905852ed838046c193f38c7df912b53
|
||||
checksum: 10c0/a64dfa0cfd5160e00ccc1d92104da03e848d310043a6c2e0dc269f197eb605d613f285d762528d3ef2dc1a83c3490cbe884a0128d0be90d01bf41e36833c516f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -750,6 +893,28 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/credential-provider-ini@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/credential-provider-ini@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-env": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-http": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-process": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-sso": "npm:3.669.0"
|
||||
"@aws-sdk/credential-provider-web-identity": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@smithy/credential-provider-imds": "npm:^3.2.4"
|
||||
"@smithy/property-provider": "npm:^3.1.7"
|
||||
"@smithy/shared-ini-file-loader": "npm:^3.1.8"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
peerDependencies:
|
||||
"@aws-sdk/client-sts": ^3.669.0
|
||||
checksum: 10c0/8feeb9b358186a19e2ba31f94e3c90b21178666473a99a9cbdb67eceb759a09de1fbd4da264a37bc30f98d9d2d5e19b2aaffeeda1c67823d6546a5ef384e49a3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/credential-provider-node@npm:3.668.0":
|
||||
version: 3.668.0
|
||||
resolution: "@aws-sdk/credential-provider-node@npm:3.668.0"
|
||||
@@ -770,6 +935,26 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/credential-provider-node@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/credential-provider-node@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-sdk/credential-provider-env": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-http": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-ini": "npm:3.669.0"
|
||||
"@aws-sdk/credential-provider-process": "npm:3.667.0"
|
||||
"@aws-sdk/credential-provider-sso": "npm:3.669.0"
|
||||
"@aws-sdk/credential-provider-web-identity": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@smithy/credential-provider-imds": "npm:^3.2.4"
|
||||
"@smithy/property-provider": "npm:^3.1.7"
|
||||
"@smithy/shared-ini-file-loader": "npm:^3.1.8"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/4484ba673e55e33fdd03782e1c0f850356ed46ab9d6bb0715e99a6c0497964b07b135e9ed515365de964ffea9cef4e0a2d4e6ac0d7f9025367395d4dff0e8abd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/credential-provider-process@npm:3.667.0":
|
||||
version: 3.667.0
|
||||
resolution: "@aws-sdk/credential-provider-process@npm:3.667.0"
|
||||
@@ -800,6 +985,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/credential-provider-sso@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/credential-provider-sso@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-sdk/client-sso": "npm:3.669.0"
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/token-providers": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@smithy/property-provider": "npm:^3.1.7"
|
||||
"@smithy/shared-ini-file-loader": "npm:^3.1.8"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/1a474e6a981b4ad7e6eb787dd8d65f9589a242d1f88329fea40017376015aedfe0c5f1d6c566d1ff53d24e4b58305de0d3efa372ddfa7a4bd539452a8b923b10
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/credential-provider-web-identity@npm:3.667.0":
|
||||
version: 3.667.0
|
||||
resolution: "@aws-sdk/credential-provider-web-identity@npm:3.667.0"
|
||||
@@ -1027,6 +1228,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/middleware-user-agent@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/middleware-user-agent@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-sdk/core": "npm:3.667.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@aws-sdk/util-endpoints": "npm:3.667.0"
|
||||
"@smithy/core": "npm:^2.4.8"
|
||||
"@smithy/protocol-http": "npm:^4.1.4"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
checksum: 10c0/d890315c40119661ac1f6b5d6fcd4bdcc5548b0b87cbbf72821a97341c95f906a49e0f6f23281e1c248f75343ec2074c1b7feaecc4fafdad6e31bb13aaeebddd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/middleware-websocket@npm:3.667.0":
|
||||
version: 3.667.0
|
||||
resolution: "@aws-sdk/middleware-websocket@npm:3.667.0"
|
||||
@@ -1171,6 +1387,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/util-user-agent-node@npm:3.669.0":
|
||||
version: 3.669.0
|
||||
resolution: "@aws-sdk/util-user-agent-node@npm:3.669.0"
|
||||
dependencies:
|
||||
"@aws-sdk/middleware-user-agent": "npm:3.669.0"
|
||||
"@aws-sdk/types": "npm:3.667.0"
|
||||
"@smithy/node-config-provider": "npm:^3.1.8"
|
||||
"@smithy/types": "npm:^3.5.0"
|
||||
tslib: "npm:^2.6.2"
|
||||
peerDependencies:
|
||||
aws-crt: ">=1.0.0"
|
||||
peerDependenciesMeta:
|
||||
aws-crt:
|
||||
optional: true
|
||||
checksum: 10c0/b3d386d7e6a12077cd2cd85d1cf242dc9319fea08841f6db6d9c1d0b45a73d4c97f5a90d85ad6a069fc2995e3ec3ffaebc4518fe466f6ea0ffa293003a1984b5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@aws-sdk/xml-builder@npm:3.662.0":
|
||||
version: 3.662.0
|
||||
resolution: "@aws-sdk/xml-builder@npm:3.662.0"
|
||||
@@ -1745,6 +1979,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@echogarden/pffft-wasm@npm:^0.3.0":
|
||||
version: 0.3.0
|
||||
resolution: "@echogarden/pffft-wasm@npm:0.3.0"
|
||||
checksum: 10c0/7425828ed23e1a1dbd77b940b0b141738337df21c0c71f8b9dbb21706b32832f70e61b0a4a441ce7bf3053433a52d48a1b905978ef01122fae0415bf31a83e46
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@echogarden/rnnoise-wasm@npm:^0.1.1":
|
||||
version: 0.1.1
|
||||
resolution: "@echogarden/rnnoise-wasm@npm:0.1.1"
|
||||
@@ -3576,9 +3817,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@langchain/core@npm:^0.3.8":
|
||||
version: 0.3.8
|
||||
resolution: "@langchain/core@npm:0.3.8"
|
||||
"@langchain/core@npm:^0.3.9":
|
||||
version: 0.3.9
|
||||
resolution: "@langchain/core@npm:0.3.9"
|
||||
dependencies:
|
||||
ansi-styles: "npm:^5.0.0"
|
||||
camelcase: "npm:6"
|
||||
@@ -3591,7 +3832,7 @@ __metadata:
|
||||
uuid: "npm:^10.0.0"
|
||||
zod: "npm:^3.22.4"
|
||||
zod-to-json-schema: "npm:^3.22.3"
|
||||
checksum: 10c0/2f1aaf17ae781d0439c6296b9ff2c8d159d6f72b8ae8a0b684d4c39d76f8072bb4d3cfa9c517946cda31bcb2fef69eb0aef2840369eb51ce47c10f4bcef50621
|
||||
checksum: 10c0/c83849308b65854495320ad73725358676f833eda50e9f67781f69af199f7fb5e5023ebaa584d45cbc8e8c4451e981695278081acf1d21b60712973c4873a07f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10302,14 +10543,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"compromise@npm:^14.14.1":
|
||||
version: 14.14.1
|
||||
resolution: "compromise@npm:14.14.1"
|
||||
"compromise@npm:^14.14.2":
|
||||
version: 14.14.2
|
||||
resolution: "compromise@npm:14.14.2"
|
||||
dependencies:
|
||||
efrt: "npm:2.7.0"
|
||||
grad-school: "npm:0.0.5"
|
||||
suffix-thumb: "npm:5.0.2"
|
||||
checksum: 10c0/07d5c6069adaf46ccfa36cbc092e9e12d3abcff283f24feb45a6a9189415dd9a22d4fd958738412c516b96257abcb3477d6596057f7de88b9e4aa87f507f3219
|
||||
checksum: 10c0/a0061b09cda899e424dc87869a4a22e616a314dc7501d506f955fa43f0bb4bd582187cb39afe6600a8190d216e7f7ae419c0ca8dfcd5f7670f6f9bb0a7f8820a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11715,17 +11956,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"echogarden@npm:^1.7.0":
|
||||
version: 1.7.0
|
||||
resolution: "echogarden@npm:1.7.0"
|
||||
"echogarden@npm:^1.8.1":
|
||||
version: 1.8.1
|
||||
resolution: "echogarden@npm:1.8.1"
|
||||
dependencies:
|
||||
"@aws-sdk/client-polly": "npm:^3.667.0"
|
||||
"@aws-sdk/client-transcribe-streaming": "npm:^3.667.0"
|
||||
"@aws-sdk/client-polly": "npm:^3.669.0"
|
||||
"@aws-sdk/client-transcribe-streaming": "npm:^3.669.0"
|
||||
"@echogarden/espeak-ng-emscripten": "npm:^0.1.2"
|
||||
"@echogarden/fasttext-wasm": "npm:^0.1.0"
|
||||
"@echogarden/flite-wasi": "npm:^0.1.1"
|
||||
"@echogarden/fvad-wasm": "npm:^0.1.2"
|
||||
"@echogarden/kissfft-wasm": "npm:^0.1.1"
|
||||
"@echogarden/pffft-wasm": "npm:^0.3.0"
|
||||
"@echogarden/rnnoise-wasm": "npm:^0.1.1"
|
||||
"@echogarden/rubberband-wasm": "npm:^0.1.1"
|
||||
"@echogarden/sonic-wasm": "npm:^0.1.1"
|
||||
@@ -11738,14 +11980,14 @@ __metadata:
|
||||
chalk: "npm:^5.3.0"
|
||||
cldr-segmentation: "npm:^2.2.1"
|
||||
command-exists: "npm:^1.2.9"
|
||||
compromise: "npm:^14.14.1"
|
||||
compromise: "npm:^14.14.2"
|
||||
fs-extra: "npm:^11.2.0"
|
||||
gaxios: "npm:^6.7.1"
|
||||
graceful-fs: "npm:^4.2.11"
|
||||
html-escaper: "npm:^3.0.3"
|
||||
html-to-text: "npm:^9.0.5"
|
||||
import-meta-resolve: "npm:^4.1.0"
|
||||
jieba-wasm: "npm:^2.1.1"
|
||||
jieba-wasm: "npm:^2.2.0"
|
||||
jsdom: "npm:^25.0.1"
|
||||
json5: "npm:^2.2.3"
|
||||
kuromoji: "npm:^0.1.2"
|
||||
@@ -12109,7 +12351,7 @@ __metadata:
|
||||
"@electron/fuses": "npm:^1.8.0"
|
||||
"@hookform/resolvers": "npm:^3.9.0"
|
||||
"@langchain/community": "npm:^0.3.4"
|
||||
"@langchain/core": "npm:^0.3.8"
|
||||
"@langchain/core": "npm:^0.3.9"
|
||||
"@langchain/ollama": "npm:^0.1.0"
|
||||
"@mozilla/readability": "npm:^0.5.0"
|
||||
"@playwright/test": "npm:^1.48.0"
|
||||
@@ -12175,13 +12417,13 @@ __metadata:
|
||||
clsx: "npm:^2.1.1"
|
||||
cmdk: "npm:^1.0.0"
|
||||
command-exists: "npm:^1.2.9"
|
||||
compromise: "npm:^14.14.1"
|
||||
compromise: "npm:^14.14.2"
|
||||
compromise-paragraphs: "npm:^0.1.0"
|
||||
compromise-stats: "npm:^0.1.0"
|
||||
dayjs: "npm:^1.11.13"
|
||||
decamelize: "npm:^6.0.0"
|
||||
decamelize-keys: "npm:^2.0.1"
|
||||
echogarden: "npm:^1.7.0"
|
||||
echogarden: "npm:^1.8.1"
|
||||
electron: "npm:^32.2.0"
|
||||
electron-context-menu: "npm:^4.0.4"
|
||||
electron-devtools-installer: "npm:^3.2.0"
|
||||
@@ -15561,10 +15803,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jieba-wasm@npm:^2.1.1":
|
||||
version: 2.1.1
|
||||
resolution: "jieba-wasm@npm:2.1.1"
|
||||
checksum: 10c0/518e58b98d3a5d996747b5ba6afd29f2d20f03d97c716aad232fa4aa0fb2780117db587916c8fae2ebe72e8bf52b0498e270849e8bc9e16bebbe33d7782e1612
|
||||
"jieba-wasm@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "jieba-wasm@npm:2.2.0"
|
||||
checksum: 10c0/1e0050b27896ae62cf3c76f428d5e8e43c228f17d3d879ef266dcddc9452074297ba27f49fa10d7e023bb74e2f99e2405e2113e12f6b3cd8ac7f8bfb3606b9d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -20852,16 +21094,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass@npm:^1.79.4":
|
||||
version: 1.79.4
|
||||
resolution: "sass@npm:1.79.4"
|
||||
"sass@npm:^1.79.5":
|
||||
version: 1.79.5
|
||||
resolution: "sass@npm:1.79.5"
|
||||
dependencies:
|
||||
"@parcel/watcher": "npm:^2.4.1"
|
||||
chokidar: "npm:^4.0.0"
|
||||
immutable: "npm:^4.0.0"
|
||||
source-map-js: "npm:>=0.6.2 <2.0.0"
|
||||
bin:
|
||||
sass: sass.js
|
||||
checksum: 10c0/505ff0d9267d0fb990971e617acfeabf7c060c55d4cef68fe8a4bc693e7ea88ae7d7caeca3975e4b453459ba4a707b6e5b6979fc9395a7e08f0a43ca6aed06b8
|
||||
checksum: 10c0/7331865fd1d0c03e6e180a4fe0e175ac1bf1214f6c77f0d99ad72fbe2ed9ede3fab8a64c0c41471cb8a358a9d11624ec59a49283f9b6070eb99c522b34b814bf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user