1
1
#[ allow( static_mut_refs) ]
2
2
mod bindings;
3
3
4
- use golem_rust:: atomically;
5
4
use crate :: bindings:: exports:: test:: llm_exports:: test_llm_api:: * ;
6
5
use crate :: bindings:: golem:: llm:: llm;
7
6
use crate :: bindings:: golem:: llm:: llm:: StreamEvent ;
8
7
use crate :: bindings:: test:: helper_client:: test_helper_client:: TestHelperApi ;
8
+ use golem_rust:: atomically;
9
+
10
+ mod utils;
9
11
10
12
struct Component ;
11
13
@@ -17,7 +19,7 @@ const MODEL: &'static str = "claude-3-7-sonnet-20250219";
17
19
const MODEL : & ' static str = "grok-3-beta" ;
18
20
#[ cfg( feature = "openrouter" ) ]
19
21
const MODEL : & ' static str = "openrouter/auto" ;
20
- #[ cfg( feature = "ollama" ) ]
22
+ #[ cfg( feature = "ollama" ) ]
21
23
const MODEL : & ' static str = "qwen3:1.7b" ;
22
24
23
25
#[ cfg( feature = "openai" ) ]
@@ -28,7 +30,7 @@ const IMAGE_MODEL: &'static str = "claude-3-7-sonnet-20250219";
28
30
const IMAGE_MODEL : & ' static str = "grok-2-vision-latest" ;
29
31
#[ cfg( feature = "openrouter" ) ]
30
32
const IMAGE_MODEL : & ' static str = "openrouter/auto" ;
31
- #[ cfg( feature = "ollama" ) ]
33
+ #[ cfg( feature = "ollama" ) ]
32
34
const IMAGE_MODEL : & ' static str = "gemma3:4b" ;
33
35
34
36
impl Guest for Component {
@@ -67,9 +69,14 @@ impl Guest for Component {
67
69
. map( |content| match content {
68
70
llm:: ContentPart :: Text ( txt) => txt,
69
71
llm:: ContentPart :: Image ( image_ref) => match image_ref {
70
- llm:: ImageReference :: Url ( url_data) => format!( "[IMAGE URL: {}]" , url_data. url) ,
71
- llm:: ImageReference :: Inline ( inline_data) => format!( "[INLINE IMAGE: {} bytes, mime: {}]" , inline_data. data. len( ) , inline_data. mime_type) ,
72
- }
72
+ llm:: ImageReference :: Url ( url_data) =>
73
+ format!( "[IMAGE URL: {}]" , url_data. url) ,
74
+ llm:: ImageReference :: Inline ( inline_data) => format!(
75
+ "[INLINE IMAGE: {} bytes, mime: {}]" ,
76
+ inline_data. data. len( ) ,
77
+ inline_data. mime_type
78
+ ) ,
79
+ } ,
73
80
} )
74
81
. collect:: <Vec <_>>( )
75
82
. join( ", " )
@@ -154,7 +161,7 @@ impl Guest for Component {
154
161
vec ! [ ]
155
162
}
156
163
} ;
157
-
164
+
158
165
if !tool_request. is_empty ( ) {
159
166
let mut calls = Vec :: new ( ) ;
160
167
for call in tool_request {
@@ -385,9 +392,14 @@ impl Guest for Component {
385
392
. map( |content| match content {
386
393
llm:: ContentPart :: Text ( txt) => txt,
387
394
llm:: ContentPart :: Image ( image_ref) => match image_ref {
388
- llm:: ImageReference :: Url ( url_data) => format!( "[IMAGE URL: {}]" , url_data. url) ,
389
- llm:: ImageReference :: Inline ( inline_data) => format!( "[INLINE IMAGE: {} bytes, mime: {}]" , inline_data. data. len( ) , inline_data. mime_type) ,
390
- }
395
+ llm:: ImageReference :: Url ( url_data) =>
396
+ format!( "[IMAGE URL: {}]" , url_data. url) ,
397
+ llm:: ImageReference :: Inline ( inline_data) => format!(
398
+ "[INLINE IMAGE: {} bytes, mime: {}]" ,
399
+ inline_data. data. len( ) ,
400
+ inline_data. mime_type
401
+ ) ,
402
+ } ,
391
403
} )
392
404
. collect:: <Vec <_>>( )
393
405
. join( ", " )
@@ -407,7 +419,7 @@ impl Guest for Component {
407
419
}
408
420
}
409
421
410
- /// test6 simulates a crash during a streaming LLM response, but only first time.
422
+ /// test6 simulates a crash during a streaming LLM response, but only first time.
411
423
/// after the automatic recovery it will continue and finish the request successfully.
412
424
fn test6 ( ) -> String {
413
425
let config = llm:: Config {
@@ -456,12 +468,20 @@ impl Guest for Component {
456
468
}
457
469
llm:: ContentPart :: Image ( image_ref) => match image_ref {
458
470
llm:: ImageReference :: Url ( url_data) => {
459
- result. push_str ( & format ! ( "IMAGE URL: {} ({:?})\n " , url_data. url, url_data. detail) ) ;
471
+ result. push_str ( & format ! (
472
+ "IMAGE URL: {} ({:?})\n " ,
473
+ url_data. url, url_data. detail
474
+ ) ) ;
460
475
}
461
476
llm:: ImageReference :: Inline ( inline_data) => {
462
- result. push_str ( & format ! ( "INLINE IMAGE: {} bytes, mime: {}, detail: {:?}\n " , inline_data. data. len( ) , inline_data. mime_type, inline_data. detail) ) ;
477
+ result. push_str ( & format ! (
478
+ "INLINE IMAGE: {} bytes, mime: {}, detail: {:?}\n " ,
479
+ inline_data. data. len( ) ,
480
+ inline_data. mime_type,
481
+ inline_data. detail
482
+ ) ) ;
463
483
}
464
- }
484
+ } ,
465
485
}
466
486
}
467
487
}
@@ -528,7 +548,10 @@ impl Guest for Component {
528
548
role : llm:: Role :: User ,
529
549
name : None ,
530
550
content : vec ! [
531
- llm:: ContentPart :: Text ( "Please describe this cat image in detail. What breed might it be?" . to_string( ) ) ,
551
+ llm:: ContentPart :: Text (
552
+ "Please describe this cat image in detail. What breed might it be?"
553
+ . to_string( ) ,
554
+ ) ,
532
555
llm:: ContentPart :: Image ( llm:: ImageReference :: Inline ( llm:: ImageSource {
533
556
data: buffer,
534
557
mime_type: "image/png" . to_string( ) ,
@@ -549,9 +572,14 @@ impl Guest for Component {
549
572
. map( |content| match content {
550
573
llm:: ContentPart :: Text ( txt) => txt,
551
574
llm:: ContentPart :: Image ( image_ref) => match image_ref {
552
- llm:: ImageReference :: Url ( url_data) => format!( "[IMAGE URL: {}]" , url_data. url) ,
553
- llm:: ImageReference :: Inline ( inline_data) => format!( "[INLINE IMAGE: {} bytes, mime: {}]" , inline_data. data. len( ) , inline_data. mime_type) ,
554
- }
575
+ llm:: ImageReference :: Url ( url_data) =>
576
+ format!( "[IMAGE URL: {}]" , url_data. url) ,
577
+ llm:: ImageReference :: Inline ( inline_data) => format!(
578
+ "[INLINE IMAGE: {} bytes, mime: {}]" ,
579
+ inline_data. data. len( ) ,
580
+ inline_data. mime_type
581
+ ) ,
582
+ } ,
555
583
} )
556
584
. collect:: <Vec <_>>( )
557
585
. join( ", " )
@@ -570,6 +598,86 @@ impl Guest for Component {
570
598
}
571
599
}
572
600
}
601
+ fn test8 ( ) -> String {
602
+ let config = llm:: Config {
603
+ model : MODEL . to_string ( ) ,
604
+ temperature : Some ( 0.2 ) ,
605
+ max_tokens : None ,
606
+ stop_sequences : None ,
607
+ tools : vec ! [ ] ,
608
+ tool_choice : None ,
609
+ provider_options : vec ! [ ] ,
610
+ } ;
611
+
612
+ let mut messages = vec ! [ llm:: Message {
613
+ role: llm:: Role :: User ,
614
+ name: Some ( "vigoo" . to_string( ) ) ,
615
+ content: vec![ llm:: ContentPart :: Text (
616
+ "Do you know what a haiku is?" . to_string( ) ,
617
+ ) ] ,
618
+ } ] ;
619
+
620
+ let stream = llm:: stream ( & messages, & config) ;
621
+
622
+ let mut result = String :: new ( ) ;
623
+
624
+ let name = std:: env:: var ( "GOLEM_WORKER_NAME" ) . unwrap ( ) ;
625
+
626
+ loop {
627
+ match utils:: consume_next_event ( & stream) {
628
+ Some ( delta) => {
629
+ result. push_str ( & delta) ;
630
+ }
631
+ None => break ,
632
+ }
633
+ }
634
+
635
+ messages. push ( llm:: Message {
636
+ role : llm:: Role :: Assistant ,
637
+ name : Some ( "assistant" . to_string ( ) ) ,
638
+ content : vec ! [ llm:: ContentPart :: Text ( result) ] ,
639
+ } ) ;
640
+
641
+ messages. push ( llm:: Message {
642
+ role : llm:: Role :: User ,
643
+ name : Some ( "vigoo" . to_string ( ) ) ,
644
+ content : vec ! [ llm:: ContentPart :: Text (
645
+ "Can you write one for me?" . to_string( ) ,
646
+ ) ] ,
647
+ } ) ;
648
+
649
+ println ! ( "Message: {messages:?}" ) ;
650
+
651
+ let stream = llm:: stream ( & messages, & config) ;
652
+
653
+ let mut result = String :: new ( ) ;
654
+
655
+ let name = std:: env:: var ( "GOLEM_WORKER_NAME" ) . unwrap ( ) ;
656
+ let mut round = 0 ;
657
+
658
+ loop {
659
+ match utils:: consume_next_event ( & stream) {
660
+ Some ( delta) => {
661
+ result. push_str ( & delta) ;
662
+ }
663
+ None => break ,
664
+ }
665
+
666
+ if round == 2 {
667
+ atomically ( || {
668
+ let client = TestHelperApi :: new ( & name) ;
669
+ let answer = client. blocking_inc_and_get ( ) ;
670
+ if answer == 1 {
671
+ panic ! ( "Simulating crash" )
672
+ }
673
+ } ) ;
674
+ }
675
+
676
+ round += 1 ;
677
+ }
678
+
679
+ result
680
+ }
573
681
}
574
682
575
683
bindings:: export!( Component with_types_in bindings) ;
0 commit comments