1
- import { elizaLogger , IAgentRuntime , ServiceType , ModelProviderName } from "@ai16z/eliza" ;
1
+ import {
2
+ elizaLogger ,
3
+ IAgentRuntime ,
4
+ ServiceType ,
5
+ ModelProviderName ,
6
+ } from "@ai16z/eliza" ;
2
7
import { Service } from "@ai16z/eliza" ;
3
8
import fs from "fs" ;
4
9
import https from "https" ;
@@ -198,13 +203,17 @@ export class LlamaService extends Service {
198
203
} catch ( error ) {
199
204
elizaLogger . error ( "Failed to initialize LlamaService:" , error ) ;
200
205
// Re-throw with more context
201
- throw new Error ( `LlamaService initialization failed: ${ error . message } ` ) ;
206
+ throw new Error (
207
+ `LlamaService initialization failed: ${ error . message } `
208
+ ) ;
202
209
}
203
210
}
204
211
205
212
private async ensureInitialized ( ) {
206
213
if ( ! this . modelInitialized ) {
207
- elizaLogger . info ( "Model not initialized, starting initialization..." ) ;
214
+ elizaLogger . info (
215
+ "Model not initialized, starting initialization..."
216
+ ) ;
208
217
await this . initializeModel ( ) ;
209
218
} else {
210
219
elizaLogger . info ( "Model already initialized" ) ;
@@ -222,9 +231,13 @@ export class LlamaService extends Service {
222
231
) ;
223
232
224
233
if ( hasCUDA ) {
225
- elizaLogger . info ( "LlamaService: CUDA detected, using GPU acceleration" ) ;
234
+ elizaLogger . info (
235
+ "LlamaService: CUDA detected, using GPU acceleration"
236
+ ) ;
226
237
} else {
227
- elizaLogger . warn ( "LlamaService: No CUDA detected - local response will be slow" ) ;
238
+ elizaLogger . warn (
239
+ "LlamaService: No CUDA detected - local response will be slow"
240
+ ) ;
228
241
}
229
242
230
243
elizaLogger . info ( "Initializing Llama instance..." ) ;
@@ -252,14 +265,24 @@ export class LlamaService extends Service {
252
265
elizaLogger . success ( "Model initialization complete" ) ;
253
266
this . processQueue ( ) ;
254
267
} catch ( error ) {
255
- elizaLogger . error ( "Model initialization failed. Deleting model and retrying:" , error ) ;
268
+ elizaLogger . error (
269
+ "Model initialization failed. Deleting model and retrying:" ,
270
+ error
271
+ ) ;
256
272
try {
257
- elizaLogger . info ( "Attempting to delete and re-download model..." ) ;
258
- await this . deleteModel ( ) ;
259
- await this . initializeModel ( ) ;
273
+ elizaLogger . info (
274
+ "Attempting to delete and re-download model..."
275
+ ) ;
276
+ await this . deleteModel ( ) ;
277
+ await this . initializeModel ( ) ;
260
278
} catch ( retryError ) {
261
- elizaLogger . error ( "Model re-initialization failed:" , retryError ) ;
262
- throw new Error ( `Model initialization failed after retry: ${ retryError . message } ` ) ;
279
+ elizaLogger . error (
280
+ "Model re-initialization failed:" ,
281
+ retryError
282
+ ) ;
283
+ throw new Error (
284
+ `Model initialization failed after retry: ${ retryError . message } `
285
+ ) ;
263
286
}
264
287
}
265
288
}
@@ -275,48 +298,83 @@ export class LlamaService extends Service {
275
298
const downloadModel = ( url : string ) => {
276
299
https
277
300
. get ( url , ( response ) => {
278
- if ( response . statusCode >= 300 && response . statusCode < 400 && response . headers . location ) {
279
- elizaLogger . info ( `Following redirect to: ${ response . headers . location } ` ) ;
301
+ if (
302
+ response . statusCode >= 300 &&
303
+ response . statusCode < 400 &&
304
+ response . headers . location
305
+ ) {
306
+ elizaLogger . info (
307
+ `Following redirect to: ${ response . headers . location } `
308
+ ) ;
280
309
downloadModel ( response . headers . location ) ;
281
- return ;
282
- }
310
+ return ;
311
+ }
283
312
284
313
if ( response . statusCode !== 200 ) {
285
- reject ( new Error ( `Failed to download model: HTTP ${ response . statusCode } ` ) ) ;
314
+ reject (
315
+ new Error (
316
+ `Failed to download model: HTTP ${ response . statusCode } `
317
+ )
318
+ ) ;
286
319
return ;
287
320
}
288
321
289
- totalSize = parseInt ( response . headers [ 'content-length' ] || '0' , 10 ) ;
290
- elizaLogger . info ( `Downloading model: Hermes-3-Llama-3.1-8B.Q8_0.gguf` ) ;
291
- elizaLogger . info ( `Download location: ${ this . modelPath } ` ) ;
292
- elizaLogger . info ( `Total size: ${ ( totalSize / 1024 / 1024 ) . toFixed ( 2 ) } MB` ) ;
322
+ totalSize = parseInt (
323
+ response . headers [ "content-length" ] || "0" ,
324
+ 10
325
+ ) ;
326
+ elizaLogger . info (
327
+ `Downloading model: Hermes-3-Llama-3.1-8B.Q8_0.gguf`
328
+ ) ;
329
+ elizaLogger . info (
330
+ `Download location: ${ this . modelPath } `
331
+ ) ;
332
+ elizaLogger . info (
333
+ `Total size: ${ ( totalSize / 1024 / 1024 ) . toFixed ( 2 ) } MB`
334
+ ) ;
293
335
294
336
response . pipe ( file ) ;
295
337
296
- let progressString = '' ;
338
+ let progressString = "" ;
297
339
response . on ( "data" , ( chunk ) => {
298
340
downloadedSize += chunk . length ;
299
- const progress = totalSize > 0 ? ( ( downloadedSize / totalSize ) * 100 ) . toFixed ( 1 ) : '0.0' ;
300
- const dots = '.' . repeat ( Math . floor ( Number ( progress ) / 5 ) ) ;
301
- progressString = `Downloading model: [${ dots . padEnd ( 20 , ' ' ) } ] ${ progress } %` ;
341
+ const progress =
342
+ totalSize > 0
343
+ ? (
344
+ ( downloadedSize / totalSize ) *
345
+ 100
346
+ ) . toFixed ( 1 )
347
+ : "0.0" ;
348
+ const dots = "." . repeat (
349
+ Math . floor ( Number ( progress ) / 5 )
350
+ ) ;
351
+ progressString = `Downloading model: [${ dots . padEnd ( 20 , " " ) } ] ${ progress } %` ;
302
352
elizaLogger . progress ( progressString ) ;
303
353
} ) ;
304
354
305
355
file . on ( "finish" , ( ) => {
306
356
file . close ( ) ;
307
- elizaLogger . progress ( '' ) ; // Clear the progress line
357
+ elizaLogger . progress ( "" ) ; // Clear the progress line
308
358
elizaLogger . success ( "Model download complete" ) ;
309
359
resolve ( ) ;
310
360
} ) ;
311
361
312
362
response . on ( "error" , ( error ) => {
313
363
fs . unlink ( this . modelPath , ( ) => { } ) ;
314
- reject ( new Error ( `Model download failed: ${ error . message } ` ) ) ;
364
+ reject (
365
+ new Error (
366
+ `Model download failed: ${ error . message } `
367
+ )
368
+ ) ;
315
369
} ) ;
316
370
} )
317
371
. on ( "error" , ( error ) => {
318
372
fs . unlink ( this . modelPath , ( ) => { } ) ;
319
- reject ( new Error ( `Model download request failed: ${ error . message } ` ) ) ;
373
+ reject (
374
+ new Error (
375
+ `Model download request failed: ${ error . message } `
376
+ )
377
+ ) ;
320
378
} ) ;
321
379
} ;
322
380
@@ -465,12 +523,15 @@ export class LlamaService extends Service {
465
523
) : Promise < any | string > {
466
524
const ollamaModel = process . env . OLLAMA_MODEL ;
467
525
if ( ollamaModel ) {
468
- const ollamaUrl = process . env . OLLAMA_SERVER_URL || 'http://localhost:11434' ;
469
- elizaLogger . info ( `Using Ollama API at ${ ollamaUrl } with model ${ ollamaModel } ` ) ;
470
-
526
+ const ollamaUrl =
527
+ process . env . OLLAMA_SERVER_URL || "http://localhost:11434" ;
528
+ elizaLogger . info (
529
+ `Using Ollama API at ${ ollamaUrl } with model ${ ollamaModel } `
530
+ ) ;
531
+
471
532
const response = await fetch ( `${ ollamaUrl } /api/generate` , {
472
- method : ' POST' ,
473
- headers : { ' Content-Type' : ' application/json' } ,
533
+ method : " POST" ,
534
+ headers : { " Content-Type" : " application/json" } ,
474
535
body : JSON . stringify ( {
475
536
model : ollamaModel ,
476
537
prompt : context ,
@@ -481,12 +542,14 @@ export class LlamaService extends Service {
481
542
frequency_penalty,
482
543
presence_penalty,
483
544
num_predict : max_tokens ,
484
- }
545
+ } ,
485
546
} ) ,
486
547
} ) ;
487
548
488
549
if ( ! response . ok ) {
489
- throw new Error ( `Ollama request failed: ${ response . statusText } ` ) ;
550
+ throw new Error (
551
+ `Ollama request failed: ${ response . statusText } `
552
+ ) ;
490
553
}
491
554
492
555
const result = await response . json ( ) ;
@@ -576,21 +639,27 @@ export class LlamaService extends Service {
576
639
async getEmbeddingResponse ( input : string ) : Promise < number [ ] | undefined > {
577
640
const ollamaModel = process . env . OLLAMA_MODEL ;
578
641
if ( ollamaModel ) {
579
- const ollamaUrl = process . env . OLLAMA_SERVER_URL || 'http://localhost:11434' ;
580
- const embeddingModel = process . env . OLLAMA_EMBEDDING_MODEL || 'mxbai-embed-large' ;
581
- elizaLogger . info ( `Using Ollama API for embeddings with model ${ embeddingModel } ` ) ;
582
-
642
+ const ollamaUrl =
643
+ process . env . OLLAMA_SERVER_URL || "http://localhost:11434" ;
644
+ const embeddingModel =
645
+ process . env . OLLAMA_EMBEDDING_MODEL || "mxbai-embed-large" ;
646
+ elizaLogger . info (
647
+ `Using Ollama API for embeddings with model ${ embeddingModel } `
648
+ ) ;
649
+
583
650
const response = await fetch ( `${ ollamaUrl } /api/embeddings` , {
584
- method : ' POST' ,
585
- headers : { ' Content-Type' : ' application/json' } ,
651
+ method : " POST" ,
652
+ headers : { " Content-Type" : " application/json" } ,
586
653
body : JSON . stringify ( {
587
654
model : embeddingModel ,
588
655
prompt : input ,
589
656
} ) ,
590
657
} ) ;
591
658
592
659
if ( ! response . ok ) {
593
- throw new Error ( `Ollama embeddings request failed: ${ response . statusText } ` ) ;
660
+ throw new Error (
661
+ `Ollama embeddings request failed: ${ response . statusText } `
662
+ ) ;
594
663
}
595
664
596
665
const result = await response . json ( ) ;
@@ -609,12 +678,15 @@ export class LlamaService extends Service {
609
678
610
679
private async ollamaCompletion ( prompt : string ) : Promise < string > {
611
680
const ollamaModel = process . env . OLLAMA_MODEL ;
612
- const ollamaUrl = process . env . OLLAMA_SERVER_URL || 'http://localhost:11434' ;
613
- elizaLogger . info ( `Using Ollama API at ${ ollamaUrl } with model ${ ollamaModel } ` ) ;
614
-
681
+ const ollamaUrl =
682
+ process . env . OLLAMA_SERVER_URL || "http://localhost:11434" ;
683
+ elizaLogger . info (
684
+ `Using Ollama API at ${ ollamaUrl } with model ${ ollamaModel } `
685
+ ) ;
686
+
615
687
const response = await fetch ( `${ ollamaUrl } /api/generate` , {
616
- method : ' POST' ,
617
- headers : { ' Content-Type' : ' application/json' } ,
688
+ method : " POST" ,
689
+ headers : { " Content-Type" : " application/json" } ,
618
690
body : JSON . stringify ( {
619
691
model : ollamaModel ,
620
692
prompt : prompt ,
@@ -625,7 +697,7 @@ export class LlamaService extends Service {
625
697
frequency_penalty : 0.5 ,
626
698
presence_penalty : 0.5 ,
627
699
num_predict : 256 ,
628
- }
700
+ } ,
629
701
} ) ,
630
702
} ) ;
631
703
@@ -639,21 +711,27 @@ export class LlamaService extends Service {
639
711
640
712
private async ollamaEmbedding ( text : string ) : Promise < number [ ] > {
641
713
const ollamaModel = process . env . OLLAMA_MODEL ;
642
- const ollamaUrl = process . env . OLLAMA_SERVER_URL || 'http://localhost:11434' ;
643
- const embeddingModel = process . env . OLLAMA_EMBEDDING_MODEL || 'mxbai-embed-large' ;
644
- elizaLogger . info ( `Using Ollama API for embeddings with model ${ embeddingModel } ` ) ;
645
-
714
+ const ollamaUrl =
715
+ process . env . OLLAMA_SERVER_URL || "http://localhost:11434" ;
716
+ const embeddingModel =
717
+ process . env . OLLAMA_EMBEDDING_MODEL || "mxbai-embed-large" ;
718
+ elizaLogger . info (
719
+ `Using Ollama API for embeddings with model ${ embeddingModel } `
720
+ ) ;
721
+
646
722
const response = await fetch ( `${ ollamaUrl } /api/embeddings` , {
647
- method : ' POST' ,
648
- headers : { ' Content-Type' : ' application/json' } ,
723
+ method : " POST" ,
724
+ headers : { " Content-Type" : " application/json" } ,
649
725
body : JSON . stringify ( {
650
726
model : embeddingModel ,
651
727
prompt : text ,
652
728
} ) ,
653
729
} ) ;
654
730
655
731
if ( ! response . ok ) {
656
- throw new Error ( `Ollama embeddings request failed: ${ response . statusText } ` ) ;
732
+ throw new Error (
733
+ `Ollama embeddings request failed: ${ response . statusText } `
734
+ ) ;
657
735
}
658
736
659
737
const result = await response . json ( ) ;
0 commit comments