diff --git a/src/components/chat-view/Chat.tsx b/src/components/chat-view/Chat.tsx index 98c4c14..f019a2d 100644 --- a/src/components/chat-view/Chat.tsx +++ b/src/components/chat-view/Chat.tsx @@ -868,7 +868,6 @@ const Chat = forwardRef((props, ref) => { > {message.content} - {/* {message.content && } */} ), )} diff --git a/src/components/chat-view/MarkdownRegexSearchFilesBlock.tsx b/src/components/chat-view/MarkdownRegexSearchFilesBlock.tsx index c629e02..55378d6 100644 --- a/src/components/chat-view/MarkdownRegexSearchFilesBlock.tsx +++ b/src/components/chat-view/MarkdownRegexSearchFilesBlock.tsx @@ -1,4 +1,4 @@ -import { FolderOpen } from 'lucide-react' +import { FileSearch } from 'lucide-react' import React from 'react' import { useApp } from '../../contexts/AppContext' @@ -44,7 +44,7 @@ export default function MarkdownRegexSearchFilesBlock({ >
- + regex search files "{regex}" in {path}
diff --git a/src/components/chat-view/MarkdownSemanticSearchFilesBlock.tsx b/src/components/chat-view/MarkdownSemanticSearchFilesBlock.tsx index b0d861c..07b6bfa 100644 --- a/src/components/chat-view/MarkdownSemanticSearchFilesBlock.tsx +++ b/src/components/chat-view/MarkdownSemanticSearchFilesBlock.tsx @@ -1,4 +1,4 @@ -import { FolderOpen } from 'lucide-react' +import { FileSearch } from 'lucide-react' import React from 'react' import { useApp } from '../../contexts/AppContext' @@ -43,7 +43,7 @@ export default function MarkdownSemanticSearchFilesBlock({ >
- + semantic search files "{query}" in {path}
diff --git a/src/components/chat-view/MarkdownWithIcon.tsx b/src/components/chat-view/MarkdownWithIcon.tsx index efe8445..2189730 100644 --- a/src/components/chat-view/MarkdownWithIcon.tsx +++ b/src/components/chat-view/MarkdownWithIcon.tsx @@ -1,16 +1,100 @@ -import { CircleCheckBig, CircleHelp } from 'lucide-react'; -import { ComponentPropsWithoutRef } from 'react'; +import * as Tooltip from '@radix-ui/react-tooltip'; +import { Check, CircleCheckBig, CircleHelp, CopyIcon, FilePlus2 } from 'lucide-react'; +import { ComponentPropsWithoutRef, useState } from 'react'; import ReactMarkdown from 'react-markdown'; import rehypeRaw from 'rehype-raw'; +import { useApp } from 'src/contexts/AppContext'; + + +function CopyButton({ message }: { message: string }) { + const [copied, setCopied] = useState(false) + + const handleCopy = async () => { + await navigator.clipboard.writeText(message.trim()) + setCopied(true) + setTimeout(() => { + setCopied(false) + }, 1500) + } + + return ( + + + + + + + + Copy message + + + + + ) +} + +function CreateNewFileButton({ message }: { message: string }) { + const app = useApp() + const [created, setCreated] = useState(false) + + const handleCreate = async () => { + const firstLine = message.split('\n')[0].trim().replace(/[\\\/:]/g, ''); + const filename = firstLine.slice(0, 200) + (firstLine.length > 200 ? '...' : '') || 'untitled'; + console.log('filename', filename) + console.log('message', message) + await app.vault.create(`/${filename}.md`, message) + setCreated(true) + setTimeout(() => { + setCreated(false) + }, 1500) + } + return ( + + + + + + + + Create new note + + + + + ) +} const MarkdownWithIcons = ({ markdownContent, className }: { markdownContent: string, className?: string }) => { // 预处理markdown内容,将标签转换为ReactMarkdown可以处理的格式 const processedContent = markdownContent.replace( /]*\/>/g, - (_, name, size, __, className) => + (_, name, size, __, className) => `` ); + const rawContent = markdownContent.replace( + /]*\/>/g, + () => `` + ).trim(); + const components = { span: (props: ComponentPropsWithoutRef<'span'> & { 'data-icon'?: string; @@ -20,7 +104,7 @@ const MarkdownWithIcons = ({ markdownContent, className }: { markdownContent: st const name = props['data-icon']; const size = props['data-size'] ? Number(props['data-size']) : 16; const className = props.className || ''; - + switch (name) { case 'ask_followup_question': return ; @@ -35,13 +119,21 @@ const MarkdownWithIcons = ({ markdownContent, className }: { markdownContent: st }; return ( - - {processedContent} - + <> + + {processedContent} + + {processedContent && +
+ + +
} + + ); }; diff --git a/src/core/prompts/sections/objective.ts b/src/core/prompts/sections/objective.ts index d0275dd..cb3d65b 100644 --- a/src/core/prompts/sections/objective.ts +++ b/src/core/prompts/sections/objective.ts @@ -10,7 +10,7 @@ You accomplish a given task iteratively, breaking it down into clear steps and w 2. Work through these goals sequentially, utilizing available tools one at a time as necessary. Each goal should correspond to a distinct step in your problem-solving process. You will be informed on the work completed and what's remaining as you go. 3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided. 4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance. -` +5. When referencing web pages, use Markdown-style links: [display text](url).` } function getObsidianObjectiveSection(): string { @@ -23,7 +23,10 @@ You accomplish a given task iteratively, breaking it down into clear steps and w 1. Analyze the user's task and set clear, achievable goals to accomplish it. Prioritize these goals in a logical order. 2. Work through these goals sequentially, utilizing available tools one at a time as necessary. Each goal should correspond to a distinct step in your problem-solving process. You will be informed on the work completed and what's remaining as you go. 3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided. -4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.` +4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance. +5. When referencing files, use Markdown-style links: [display text](file-path.md). Follow these rules: + - Always use full relative paths (e.g., [Daily/2024-04/26.md](Daily/2024-04/26.md) + - Never use bare filenames without links (e.g., ✗ "26.md")` } export function getObjectiveSection(mode: string): string { diff --git a/src/utils/prompt-generator.ts b/src/utils/prompt-generator.ts index ffd02c8..a70f3b6 100644 --- a/src/utils/prompt-generator.ts +++ b/src/utils/prompt-generator.ts @@ -16,7 +16,7 @@ import { MentionableVault } from '../types/mentionable' import { InfioSettings } from '../types/settings' -import { Mode, defaultModeSlug, getFullModeDetails, getModeBySlug } from "../utils/modes" +import { Mode, getFullModeDetails } from "../utils/modes" import { readTFileContent