@@ -103,6 +103,72 @@ async function verifyHuggingFaceKey(apiKey) {
103103 if ( ! res . ok ) throw new Error ( `Hugging Face token invalid (${ res . status } ): ${ text . slice ( 0 , 300 ) } ` ) ;
104104}
105105
106+ async function verifyFirecrawlKey ( apiKey ) {
107+ const { res, text } = await fetchTextWithTimeout ( 'https://api.firecrawl.dev/v1/search' , {
108+ method : 'POST' ,
109+ headers : {
110+ Authorization : `Bearer ${ apiKey } ` ,
111+ 'Content-Type' : 'application/json'
112+ } ,
113+ body : JSON . stringify ( {
114+ query : 'example.com' ,
115+ limit : 1
116+ } )
117+ } , 45000 , 'Firecrawl auth' ) ;
118+ if ( ! res . ok ) throw new Error ( `Firecrawl key invalid (${ res . status } ): ${ text . slice ( 0 , 300 ) } ` ) ;
119+ }
120+
121+ async function verifyJinaKey ( apiKey ) {
122+ const { res, text } = await fetchTextWithTimeout ( 'https://r.jina.ai/http://example.com' , {
123+ method : 'GET' ,
124+ headers : {
125+ Authorization : `Bearer ${ apiKey } ` ,
126+ Accept : 'text/plain'
127+ }
128+ } , 45000 , 'Jina auth' ) ;
129+ if ( ! res . ok ) throw new Error ( `Jina key invalid (${ res . status } ): ${ text . slice ( 0 , 300 ) } ` ) ;
130+ }
131+
132+ async function verifyDriftbotKey ( apiKey ) {
133+ const query = encodeURIComponent ( 'type:Person' ) ;
134+ const url = `https://kg.diffbot.com/kg/v3/dql?token=${ encodeURIComponent ( apiKey ) } &query=${ query } &size=1` ;
135+ const { res, text } = await fetchTextWithTimeout ( url , {
136+ method : 'GET' ,
137+ headers : { Accept : 'application/json' }
138+ } , 45000 , 'Driftbot auth' ) ;
139+ if ( ! res . ok ) throw new Error ( `Driftbot key invalid (${ res . status } ): ${ text . slice ( 0 , 300 ) } ` ) ;
140+ }
141+
142+ async function verifyLlamaCloudKey ( apiKey ) {
143+ if ( ! String ( apiKey || '' ) . trim ( ) . startsWith ( 'llx-' ) ) {
144+ throw new Error ( 'LlamaCloud key format invalid (expected llx-)' ) ;
145+ }
146+ const base = String ( process . env . LLAMAPARSE_BASE_URL || process . env . LLAMA_CLOUD_BASE_URL || 'https://api.cloud.llamaindex.ai' )
147+ . trim ( )
148+ . replace ( / \/ + $ / , '' ) ;
149+ const { res, text } = await fetchTextWithTimeout ( `${ base } /api/v1/parsing/upload` , {
150+ method : 'POST' ,
151+ headers : { Authorization : `Bearer ${ apiKey } ` }
152+ } , 30000 , 'LlamaParse auth' ) ;
153+ if ( res . status === 401 || res . status === 403 ) {
154+ throw new Error ( `LlamaParse key invalid (${ res . status } ): ${ text . slice ( 0 , 300 ) } ` ) ;
155+ }
156+ }
157+
158+ async function verifyAssemblyAiKey ( apiKey ) {
159+ const { res, text } = await fetchTextWithTimeout ( 'https://api.assemblyai.com/v2/transcript' , {
160+ method : 'POST' ,
161+ headers : {
162+ Authorization : apiKey ,
163+ 'Content-Type' : 'application/json'
164+ } ,
165+ body : JSON . stringify ( { } )
166+ } , 30000 , 'AssemblyAI auth' ) ;
167+ if ( res . status === 401 || res . status === 403 ) {
168+ throw new Error ( `AssemblyAI key invalid (${ res . status } ): ${ text . slice ( 0 , 300 ) } ` ) ;
169+ }
170+ }
171+
106172async function verifyAllProviderCredentials ( providerEnv , options = { } ) {
107173 const strictAll = Boolean ( options . strictAll ) ;
108174 const checks = [ ] ;
@@ -133,6 +199,31 @@ async function verifyAllProviderCredentials(providerEnv, options = {}) {
133199 enabled : Boolean ( key ( 'HUGGINGFACE_INFERENCE_API_TOKEN' ) ) ,
134200 run : ( ) => verifyHuggingFaceKey ( key ( 'HUGGINGFACE_INFERENCE_API_TOKEN' ) )
135201 } ) ;
202+ checks . push ( {
203+ name : 'firecrawl' ,
204+ enabled : Boolean ( key ( 'FIRECRAWL_API_KEY' ) ) ,
205+ run : ( ) => verifyFirecrawlKey ( key ( 'FIRECRAWL_API_KEY' ) )
206+ } ) ;
207+ checks . push ( {
208+ name : 'jina' ,
209+ enabled : Boolean ( key ( 'JINA_API_KEY' ) ) ,
210+ run : ( ) => verifyJinaKey ( key ( 'JINA_API_KEY' ) )
211+ } ) ;
212+ checks . push ( {
213+ name : 'driftbot' ,
214+ enabled : Boolean ( key ( 'DRIFTBOT_API_KEY' ) ) ,
215+ run : ( ) => verifyDriftbotKey ( key ( 'DRIFTBOT_API_KEY' ) )
216+ } ) ;
217+ checks . push ( {
218+ name : 'llamaparse' ,
219+ enabled : Boolean ( key ( 'LLAMA_CLOUD_API_KEY' ) ) ,
220+ run : ( ) => verifyLlamaCloudKey ( key ( 'LLAMA_CLOUD_API_KEY' ) )
221+ } ) ;
222+ checks . push ( {
223+ name : 'assemblyai' ,
224+ enabled : Boolean ( key ( 'ASSEMBLYAI_API_KEY' ) ) ,
225+ run : ( ) => verifyAssemblyAiKey ( key ( 'ASSEMBLYAI_API_KEY' ) )
226+ } ) ;
136227
137228 const failures = [ ] ;
138229 for ( const check of checks ) {
@@ -455,8 +546,10 @@ async function main() {
455546 loadEnvFiles ( [
456547 path . join ( repoRoot , '.env.local' ) ,
457548 path . join ( repoRoot , '.env.e2e.local' ) ,
549+ path . join ( repoRoot , '.crawler' ) ,
458550 path . join ( repoRoot , 'comicbot/.env' ) ,
459- path . join ( repoRoot , 'telegram/.env' )
551+ path . join ( repoRoot , 'telegram/.env' ) ,
552+ path . join ( repoRoot , 'telegram/.crawler' )
460553 ] ) ;
461554
462555 const args = preArgs ;
@@ -508,7 +601,12 @@ async function main() {
508601 OPENROUTER_API_KEY : firstNonEmpty ( args [ 'openrouter-key' ] , process . env . OPENROUTER_API_KEY ) ,
509602 CLOUDFLARE_ACCOUNT_ID : cloudflareAccountId ,
510603 CLOUDFLARE_API_TOKEN : cloudflareAiToken ,
511- HUGGINGFACE_INFERENCE_API_TOKEN : firstNonEmpty ( args [ 'huggingface-token' ] , process . env . HUGGINGFACE_INFERENCE_API_TOKEN )
604+ HUGGINGFACE_INFERENCE_API_TOKEN : firstNonEmpty ( args [ 'huggingface-token' ] , process . env . HUGGINGFACE_INFERENCE_API_TOKEN ) ,
605+ FIRECRAWL_API_KEY : firstNonEmpty ( args [ 'firecrawl-key' ] , process . env . FIRECRAWL_API_KEY ) ,
606+ JINA_API_KEY : firstNonEmpty ( args [ 'jina-key' ] , process . env . JINA_API_KEY ) ,
607+ DRIFTBOT_API_KEY : firstNonEmpty ( args [ 'driftbot-key' ] , process . env . DRIFTBOT_API_KEY ) ,
608+ LLAMA_CLOUD_API_KEY : firstNonEmpty ( args [ 'llama-cloud-key' ] , process . env . LLAMA_CLOUD_API_KEY , process . env . LLAMAPARSE_API_KEY ) ,
609+ ASSEMBLYAI_API_KEY : firstNonEmpty ( args [ 'assemblyai-key' ] , process . env . ASSEMBLYAI_API_KEY )
512610 } ;
513611 const resolvedR2 = resolveR2Config ( args , cfYaml , awsYaml ) ;
514612 const r2Env = {
0 commit comments