feat: support custon endpint for Firecrawl
This commit is contained in:
@ -11,6 +11,7 @@
|
||||
const {
|
||||
config,
|
||||
aiApiBase,
|
||||
webSearchApiBase,
|
||||
showConfigManager: showModal,
|
||||
} = storeToRefs(useConfigStore())
|
||||
const { t } = useI18n()
|
||||
@ -66,6 +67,7 @@
|
||||
// Only kept for easy reference in i18n Ally
|
||||
_help: t('settings.webSearch.providers.firecrawl.help'),
|
||||
link: 'https://www.firecrawl.dev/app/api-keys',
|
||||
supportsCustomApiBase: true,
|
||||
},
|
||||
])
|
||||
const selectedAiProvider = computed(() =>
|
||||
@ -121,6 +123,7 @@
|
||||
config.value.ai.model = model
|
||||
}
|
||||
|
||||
// Automatically fetch AI models list
|
||||
watch(
|
||||
() => [
|
||||
config.value.ai.provider,
|
||||
@ -134,6 +137,24 @@
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
// Reset AI config when provider changed
|
||||
watch(
|
||||
() => config.value.ai.provider,
|
||||
() => {
|
||||
config.value.ai.apiKey = ''
|
||||
config.value.ai.apiBase = ''
|
||||
config.value.ai.model = ''
|
||||
config.value.ai.contextSize = undefined
|
||||
},
|
||||
)
|
||||
// Reset web search config when provider changed
|
||||
watch(
|
||||
() => config.value.webSearch.provider,
|
||||
() => {
|
||||
config.value.webSearch.apiKey = ''
|
||||
config.value.webSearch.apiBase = ''
|
||||
},
|
||||
)
|
||||
|
||||
defineExpose({
|
||||
show() {
|
||||
@ -250,17 +271,30 @@
|
||||
</template>
|
||||
<USelect
|
||||
v-model="config.webSearch.provider"
|
||||
class="w-auto"
|
||||
class="w-30"
|
||||
:items="webSearchProviderOptions"
|
||||
/>
|
||||
</UFormField>
|
||||
<UFormField :label="$t('settings.webSearch.apiKey')" required>
|
||||
<UFormField
|
||||
:label="$t('settings.webSearch.apiKey')"
|
||||
:required="!config.webSearch.apiBase"
|
||||
>
|
||||
<PasswordInput
|
||||
v-model="config.webSearch.apiKey"
|
||||
class="w-full"
|
||||
:placeholder="$t('settings.webSearch.apiKey')"
|
||||
/>
|
||||
</UFormField>
|
||||
<UFormField
|
||||
v-if="selectedWebSearchProvider?.supportsCustomApiBase"
|
||||
:label="$t('settings.webSearch.apiBase')"
|
||||
>
|
||||
<UInput
|
||||
v-model="config.webSearch.apiBase"
|
||||
class="w-full"
|
||||
:placeholder="webSearchApiBase"
|
||||
/>
|
||||
</UFormField>
|
||||
<UFormField :label="$t('settings.webSearch.queryLanguage')">
|
||||
<template #help>
|
||||
<i18n-t
|
||||
|
@ -19,12 +19,13 @@ type WebSearchFunction = (
|
||||
) => Promise<WebSearchResult[]>
|
||||
|
||||
export const useWebSearch = (): WebSearchFunction => {
|
||||
const { config } = useConfigStore()
|
||||
const { config, webSearchApiBase } = useConfigStore()
|
||||
|
||||
switch (config.webSearch.provider) {
|
||||
case 'firecrawl': {
|
||||
const fc = new Firecrawl({
|
||||
apiKey: config.webSearch.apiKey,
|
||||
apiUrl: webSearchApiBase,
|
||||
})
|
||||
return async (q: string, o: WebSearchOptions) => {
|
||||
const results = await fc.search(q, o)
|
||||
|
@ -40,11 +40,12 @@
|
||||
"help": "Similar to Firecrawl, but provides 1000 free credits / month. Get one API key at {0}."
|
||||
},
|
||||
"firecrawl": {
|
||||
"help": "Get one API key at {0}."
|
||||
"help": "Get one API key at {0} if you are using the official service."
|
||||
}
|
||||
},
|
||||
"concurrencyLimitHelp": "Limit the concurrent search tasks. This is useful to avoid overloading the search provider and causing requests to fail.",
|
||||
"concurrencyLimit": "Concurrency Limit"
|
||||
"concurrencyLimit": "Concurrency Limit",
|
||||
"apiBase": "API Base URL"
|
||||
}
|
||||
},
|
||||
"researchTopic": {
|
||||
@ -74,7 +75,6 @@
|
||||
"clickToView": "Click a child node to view details.",
|
||||
"nodeDetails": "Node Details",
|
||||
"startNode": {
|
||||
"label": "Start",
|
||||
"description": "This is the beginning of your deep research journey!"
|
||||
},
|
||||
"researchGoal": "Research Goal",
|
||||
|
@ -37,14 +37,15 @@
|
||||
"queryLanguageHelp": "修改搜索词的语言。如果你想获取不同的搜索结果(比如查询高质量的英文资料),可以在这里修改。\nAI 模型在总结的时候仍然会使用当前网页的语言。",
|
||||
"providers": {
|
||||
"firecrawl": {
|
||||
"help": "在 {0} 获取一个 API key。"
|
||||
"help": "如果你使用的是官方服务,请在 {0} 获取 API key。"
|
||||
},
|
||||
"tavily": {
|
||||
"help": "和 Firecrawl 类似,不过提供了每月 1000 次免费搜索。在 {0} 获取一个 API key。"
|
||||
}
|
||||
},
|
||||
"concurrencyLimit": "并发数",
|
||||
"concurrencyLimitHelp": "限制同时进行的搜索数量。这样可以避免被 API 服务限流,导致请求失败。"
|
||||
"concurrencyLimitHelp": "限制同时进行的搜索数量。这样可以避免被 API 服务限流,导致请求失败。",
|
||||
"apiBase": "API Base URL"
|
||||
}
|
||||
},
|
||||
"researchTopic": {
|
||||
@ -74,7 +75,6 @@
|
||||
"clickToView": "点击下面的节点查看搜索详情。",
|
||||
"nodeDetails": "节点详情",
|
||||
"startNode": {
|
||||
"label": "Start",
|
||||
"description": "这是本次研究的起点"
|
||||
},
|
||||
"researchGoal": "研究目标",
|
||||
|
@ -20,6 +20,8 @@ export interface ConfigAi {
|
||||
export interface ConfigWebSearch {
|
||||
provider: ConfigWebSearchProvider
|
||||
apiKey?: string
|
||||
/** API base. Currently only works with Firecrawl */
|
||||
apiBase?: string
|
||||
/** Force the LLM to generate serp queries in a certain language */
|
||||
searchLanguage?: Locale
|
||||
/** Limit the number of concurrent tasks globally */
|
||||
@ -78,6 +80,15 @@ export const useConfigStore = defineStore('config', () => {
|
||||
}
|
||||
return ai.apiBase || 'https://api.openai.com/v1'
|
||||
})
|
||||
const webSearchApiBase = computed(() => {
|
||||
const { webSearch } = config.value
|
||||
if (webSearch.provider === 'tavily') {
|
||||
return
|
||||
}
|
||||
if (webSearch.provider === 'firecrawl') {
|
||||
return webSearch.apiBase || 'https://api.firecrawl.dev'
|
||||
}
|
||||
})
|
||||
|
||||
const showConfigManager = ref(false)
|
||||
|
||||
@ -85,6 +96,7 @@ export const useConfigStore = defineStore('config', () => {
|
||||
config: skipHydrate(config),
|
||||
isConfigValid,
|
||||
aiApiBase,
|
||||
webSearchApiBase,
|
||||
showConfigManager,
|
||||
dismissUpdateVersion: skipHydrate(dismissUpdateVersion),
|
||||
}
|
||||
|
Reference in New Issue
Block a user