1
+ import type { Config , ConfigAi , ConfigWebSearch } from '~/app/stores/config'
2
+
3
+ /**
4
+ * Server-side configuration loaded from environment variables
5
+ */
6
+ export interface ServerConfig {
7
+ /** Whether the server has valid AI configuration */
8
+ hasAiConfig : boolean
9
+ /** Whether the server has valid web search configuration */
10
+ hasWebSearchConfig : boolean
11
+ /** The AI configuration from environment variables */
12
+ ai : ConfigAi
13
+ /** The web search configuration from environment variables */
14
+ webSearch : ConfigWebSearch
15
+ }
16
+
17
+ /**
18
+ * Read environment variables for AI configuration
19
+ */
20
+ function getAiConfig ( ) : ConfigAi {
21
+ const provider = process . env . AI_PROVIDER as ConfigAi [ 'provider' ] || 'openai-compatible'
22
+ const apiKey = process . env . AI_API_KEY || ''
23
+ const apiBase = process . env . AI_API_BASE || ''
24
+ const model = process . env . AI_MODEL || ''
25
+ const contextSize = process . env . AI_CONTEXT_SIZE
26
+ ? parseInt ( process . env . AI_CONTEXT_SIZE , 10 )
27
+ : 128_000
28
+
29
+ return {
30
+ provider,
31
+ apiKey,
32
+ apiBase,
33
+ model,
34
+ contextSize
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Read environment variables for web search configuration
40
+ */
41
+ function getWebSearchConfig ( ) : ConfigWebSearch {
42
+ const provider = process . env . WEB_SEARCH_PROVIDER as ConfigWebSearch [ 'provider' ] || 'tavily'
43
+ const apiKey = process . env . WEB_SEARCH_API_KEY || ''
44
+ const apiBase = process . env . WEB_SEARCH_API_BASE || ''
45
+ const searchLanguage = process . env . WEB_SEARCH_LANGUAGE as ConfigWebSearch [ 'searchLanguage' ]
46
+ const concurrencyLimit = process . env . WEB_SEARCH_CONCURRENCY_LIMIT
47
+ ? parseInt ( process . env . WEB_SEARCH_CONCURRENCY_LIMIT , 10 )
48
+ : 2
49
+
50
+ // Tavily specific config
51
+ const tavilyAdvancedSearch = process . env . TAVILY_ADVANCED_SEARCH === 'true'
52
+ const tavilySearchTopic = process . env . TAVILY_SEARCH_TOPIC as ConfigWebSearch [ 'tavilySearchTopic' ] || 'general'
53
+
54
+ return {
55
+ provider,
56
+ apiKey,
57
+ apiBase,
58
+ searchLanguage,
59
+ concurrencyLimit,
60
+ tavilyAdvancedSearch,
61
+ tavilySearchTopic
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Validate AI configuration
67
+ */
68
+ function validateAiConfig ( config : ConfigAi ) : boolean {
69
+ if ( config . provider !== 'ollama' && ! config . apiKey ) return false
70
+ if ( typeof config . contextSize !== 'undefined' && config . contextSize < 0 ) return false
71
+ if ( ! config . model ) return false
72
+ return true
73
+ }
74
+
75
+ /**
76
+ * Validate web search configuration
77
+ */
78
+ function validateWebSearchConfig ( config : ConfigWebSearch ) : boolean {
79
+ if ( config . provider === 'tavily' && ! config . apiKey ) return false
80
+ // Either apiBase or apiKey is required for firecrawl
81
+ if ( config . provider === 'firecrawl' && ! config . apiBase && ! config . apiKey ) return false
82
+ if ( typeof config . concurrencyLimit !== 'undefined' && config . concurrencyLimit ! < 1 ) return false
83
+ return true
84
+ }
85
+
86
+ /**
87
+ * Get the server-side configuration from environment variables
88
+ */
89
+ export function getServerConfig ( ) : ServerConfig {
90
+ const ai = getAiConfig ( )
91
+ const webSearch = getWebSearchConfig ( )
92
+
93
+ const hasAiConfig = validateAiConfig ( ai )
94
+ const hasWebSearchConfig = validateWebSearchConfig ( webSearch )
95
+
96
+ return {
97
+ hasAiConfig,
98
+ hasWebSearchConfig,
99
+ ai,
100
+ webSearch
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Get the full configuration, combining server and client config.
106
+ * Client config takes precedence when provided.
107
+ */
108
+ export function getMergedConfig ( clientConfig ?: Config ) : Config {
109
+ const serverConfig = getServerConfig ( )
110
+
111
+ if ( ! clientConfig ) {
112
+ return {
113
+ ai : serverConfig . ai ,
114
+ webSearch : serverConfig . webSearch
115
+ }
116
+ }
117
+
118
+ return {
119
+ ai : clientConfig . ai || serverConfig . ai ,
120
+ webSearch : clientConfig . webSearch || serverConfig . webSearch
121
+ }
122
+ }
0 commit comments