diff --git a/components/ConfigManager.vue b/components/ConfigManager.vue
index 5ba9a99..b946f27 100644
--- a/components/ConfigManager.vue
+++ b/components/ConfigManager.vue
@@ -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 @@
-
+
+
+
+
Promise
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)
diff --git a/i18n/en.json b/i18n/en.json
index de5c60b..cf8334a 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -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",
@@ -106,4 +106,4 @@
"refresh": "Refresh page",
"dismiss": "Dismiss"
}
-}
\ No newline at end of file
+}
diff --git a/i18n/zh.json b/i18n/zh.json
index d41b8b5..893d42b 100644
--- a/i18n/zh.json
+++ b/i18n/zh.json
@@ -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": "研究目标",
@@ -106,4 +106,4 @@
"refresh": "刷新",
"dismiss": "忽略"
}
-}
\ No newline at end of file
+}
diff --git a/stores/config.ts b/stores/config.ts
index 42b944a..2481a34 100644
--- a/stores/config.ts
+++ b/stores/config.ts
@@ -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),
}