update research mode, add search web and fetch url content

This commit is contained in:
duanfuxiang
2025-03-15 08:17:10 +08:00
parent 05b1302a6c
commit 9a5e5f3880
12 changed files with 553 additions and 7 deletions

View File

@@ -44,6 +44,7 @@ import {
import { readTFileContent } from '../../utils/obsidian'
import { openSettingsModalWithError } from '../../utils/open-settings-modal'
import { PromptGenerator, addLineNumbers } from '../../utils/prompt-generator'
import { fetchUrlsContent, webSearch } from '../../utils/web-search'
// Simple file reading function that returns a placeholder content for testing
const readFileContent = (filePath: string): string => {
@@ -283,7 +284,7 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
chatModel,
{
model: chatModel.modelId,
temperature: 0.5,
temperature: 0,
messages: requestMessages,
stream: true,
},
@@ -532,6 +533,38 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
mentionables: [],
}
}
} else if (toolArgs.type === 'search_web') {
const results = await webSearch(toolArgs.query)
const formattedContent = `[search_web for '${toolArgs.query}'] Result:\n${results}\n`;
return {
type: 'search_web',
applyMsgId,
applyStatus: ApplyStatus.Applied,
returnMsg: {
role: 'user',
applyStatus: ApplyStatus.Idle,
content: null,
promptContent: formattedContent,
id: uuidv4(),
mentionables: [],
}
}
} else if (toolArgs.type === 'fetch_urls_content') {
const results = await fetchUrlsContent(toolArgs.urls)
const formattedContent = `[ fetch_urls_content ] Result:\n${results}\n`;
return {
type: 'fetch_urls_content',
applyMsgId,
applyStatus: ApplyStatus.Applied,
returnMsg: {
role: 'user',
applyStatus: ApplyStatus.Idle,
content: null,
promptContent: formattedContent,
id: uuidv4(),
mentionables: [],
}
}
}
} catch (error) {
console.error('Failed to apply changes', error)

View File

@@ -0,0 +1,81 @@
import { ChevronDown, ChevronRight, Globe } from 'lucide-react'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import { useDarkModeContext } from '../../contexts/DarkModeContext'
import { ApplyStatus, FetchUrlsContentToolArgs } from '../../types/apply'
import { MemoizedSyntaxHighlighterWrapper } from './SyntaxHighlighterWrapper'
export default function MarkdownFetchUrlsContentBlock({
applyStatus,
onApply,
urls,
finish
}: {
applyStatus: ApplyStatus
onApply: (args: FetchUrlsContentToolArgs) => void
urls: string[],
finish: boolean
}) {
const { isDarkMode } = useDarkModeContext()
const containerRef = useRef<HTMLDivElement>(null)
const [isOpen, setIsOpen] = useState(true)
React.useEffect(() => {
console.log('finish', finish, applyStatus)
if (finish && applyStatus === ApplyStatus.Idle) {
console.log('finish auto fetch urls content', urls)
onApply({
type: 'fetch_urls_content',
urls: urls
})
}
}, [finish])
const urlsMarkdownContent = useMemo(() => {
return urls.map(url => {
return `${url}`
}).join('\n\n')
}, [urls])
useEffect(() => {
if (containerRef.current) {
containerRef.current.scrollTop = containerRef.current.scrollHeight
}
}, [urlsMarkdownContent])
return (
urlsMarkdownContent && (
<div
className={`infio-chat-code-block has-filename infio-reasoning-block`}
>
<div className={'infio-chat-code-block-header'}>
<div className={'infio-chat-code-block-header-filename'}>
<Globe size={10} className="infio-chat-code-block-header-icon" />
Fetch URLs Content
</div>
<button
className="clickable-icon infio-chat-list-dropdown"
onClick={() => setIsOpen(!isOpen)}
>
{isOpen ? <ChevronDown size={16} /> : <ChevronRight size={16} />}
</button>
</div>
<div
ref={containerRef}
className="infio-reasoning-content-wrapper"
>
<MemoizedSyntaxHighlighterWrapper
isDarkMode={isDarkMode}
language="markdown"
hasFilename={true}
wrapLines={true}
isOpen={isOpen}
>
{urlsMarkdownContent}
</MemoizedSyntaxHighlighterWrapper>
</div>
</div>
)
)
}

View File

@@ -0,0 +1,41 @@
import { Search } from 'lucide-react'
import React from 'react'
import { ApplyStatus, SearchWebToolArgs } from '../../types/apply'
export default function MarkdownWebSearchBlock({
applyStatus,
onApply,
query,
finish
}: {
applyStatus: ApplyStatus
onApply: (args: SearchWebToolArgs) => void
query: string,
finish: boolean
}) {
React.useEffect(() => {
console.log('finish', finish, applyStatus)
if (finish && applyStatus === ApplyStatus.Idle) {
console.log('finish auto web search', query)
onApply({
type: 'search_web',
query: query,
})
}
}, [finish])
return (
<div
className={`infio-chat-code-block has-filename`}
>
<div className={'infio-chat-code-block-header'}>
<div className={'infio-chat-code-block-header-filename'}>
<Search size={14} className="infio-chat-code-block-header-icon" />
Web search: {query}
</div>
</div>
</div>
)
}

View File

@@ -8,14 +8,15 @@ import {
} from '../../utils/parse-infio-block'
import MarkdownEditFileBlock from './MarkdownEditFileBlock'
import MarkdownFetchUrlsContentBlock from './MarkdownFetchUrlsContentBlock'
import MarkdownListFilesBlock from './MarkdownListFilesBlock'
import MarkdownReadFileBlock from './MarkdownReadFileBlock'
import MarkdownReasoningBlock from './MarkdownReasoningBlock'
import MarkdownRegexSearchFilesBlock from './MarkdownRegexSearchFilesBlock'
import MarkdownSearchAndReplace from './MarkdownSearchAndReplace'
import MarkdownSearchWebBlock from './MarkdownSearchWebBlock'
import MarkdownSemanticSearchFilesBlock from './MarkdownSemanticSearchFilesBlock'
import MarkdownWithIcons from './MarkdownWithIcon'
function ReactMarkdown({
applyStatus,
onApply,
@@ -131,6 +132,22 @@ function ReactMarkdown({
markdownContent={
`<icon name='ask_followup_question' size={14} className="infio-markdown-icon" />
${block.question && block.question.trimStart()}`} />
) : block.type === 'search_web' ? (
<MarkdownSearchWebBlock
key={"search-web-" + index}
applyStatus={applyStatus}
onApply={onApply}
query={block.query}
finish={block.finish}
/>
) : block.type === 'fetch_urls_content' ? (
<MarkdownFetchUrlsContentBlock
key={"fetch-urls-content-" + index}
applyStatus={applyStatus}
onApply={onApply}
urls={block.urls}
finish={block.finish}
/>
) : (
<Markdown key={"markdown-" + index} className="infio-markdown">
{block.content}