2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  server  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"testing" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/gin-gonic/gin" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/google/go-cmp/cmp" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/ollama/ollama/api" 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-17 08:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/ollama/ollama/discover" 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-14 08:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/ollama/ollama/fs/ggml" 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/ollama/ollama/llm" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  mockRunner  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									llm . LlamaServer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// CompletionRequest is only valid until the next call to Completion
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									llm . CompletionRequest 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									llm . CompletionResponse 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CompletionFn  func ( context . Context ,  llm . CompletionRequest ,  func ( llm . CompletionResponse ) )  error 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( m  * mockRunner )  Completion ( ctx  context . Context ,  r  llm . CompletionRequest ,  fn  func ( r  llm . CompletionResponse ) )  error  {  
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									m . CompletionRequest  =  r 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  m . CompletionFn  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  m . CompletionFn ( ctx ,  r ,  fn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									fn ( m . CompletionResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( mockRunner )  Tokenize ( _  context . Context ,  s  string )  ( tokens  [ ] int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  range  strings . Fields ( s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tokens  =  append ( tokens ,  len ( tokens ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-14 08:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newMockServer ( mock  * mockRunner )  func ( discover . GpuInfoList ,  string ,  * ggml . GGML ,  [ ] string ,  [ ] string ,  api . Options ,  int )  ( llm . LlamaServer ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  func ( _  discover . GpuInfoList ,  _  string ,  _  * ggml . GGML ,  _ ,  _  [ ] string ,  _  api . Options ,  _  int )  ( llm . LlamaServer ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  mock ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestGenerateChat ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gin . SetMode ( gin . TestMode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock  :=  mockRunner { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CompletionResponse :  llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Done :                true , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-04 01:19:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											DoneReason :          llm . DoneReasonStop , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											PromptEvalCount :     1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EvalCount :           1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EvalDuration :        1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  Server { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sched :  & Scheduler { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pendingReqCh :   make ( chan  * LlmRequest ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishedReqCh :  make ( chan  * LlmRequest ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expiredCh :      make ( chan  * runnerRef ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unloadedCh :     make ( chan  any ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											loaded :         make ( map [ string ] * runnerRef ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newServerFn :    newMockServer ( & mock ) , 
							 
						 
					
						
							
								
									
										
										
										
											2025-10-02 06:12:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											getGpuFn :       getGpuFn , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											getCpuFn :       getCpuFn , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											reschedDelay :   250  *  time . Millisecond , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-30 03:21:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											loadFn :  func ( req  * LlmRequest ,  _  * ggml . GGML ,  _  discover . GpuInfoList ,  _  bool )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-20 10:11:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// add small delay to simulate loading
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												time . Sleep ( time . Millisecond ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												req . successCh  <-  & runnerRef { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													llama :  & mock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-30 03:21:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  false 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-09 02:42:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  s . sched . Run ( t . Context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-14 08:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  digest  :=  createBinFile ( t ,  ggml . KV { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"general.architecture" :           "llama" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.block_count" :              uint32 ( 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.context_length" :           uint32 ( 8192 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.embedding_length" :         uint32 ( 4096 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.attention.head_count" :     uint32 ( 32 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.attention.head_count_kv" :  uint32 ( 8 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"tokenizer.ggml.tokens" :          [ ] string { "" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"tokenizer.ggml.scores" :          [ ] float32 { 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"tokenizer.ggml.token_type" :      [ ] int32 { 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 02:20:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ,  [ ] * ggml . Tensor { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ Name :  "token_embd.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_norm.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_down.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_gate.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_up.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_norm.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_k.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_output.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_q.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_v.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "output.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  :=  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Model :  "test" , 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Files :  map [ string ] string { "file.gguf" :  digest } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Template :  ` 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ { -  if  . Tools  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ {  . Tools  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ {  end  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  range  . Messages  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  . Role  } } :  { {  . Content  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  range  . ToolCalls  } } { "name" :  "{{ .Function.Name }}" ,  "arguments" :  { {  . Function . Arguments  } } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  end  } }  
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ {  end  } } ` ,  
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "missing body" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusBadRequest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 400, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"model is required"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-29 10:38:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . Run ( "missing thinking capability" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										think  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "Hello!" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-06 03:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Think :  & api . ThinkValue { Value :  think } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-29 10:38:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusBadRequest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 400, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"registry.ollama.ai/library/test:latest does not support thinking"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t . Run ( "missing model" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusBadRequest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 400, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"model is required"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . Run ( "missing capabilities chat" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-14 08:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  digest  :=  createBinFile ( t ,  ggml . KV { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											"general.architecture" :  "bert" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"bert.pooling_type" :     uint32 ( 0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 02:20:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  [ ] * ggml . Tensor { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Model :   "bert" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Files :   map [ string ] string { "bert.gguf" :  digest } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  =  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "bert" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusBadRequest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 400, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"\"bert\" does not support chat"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "load model" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  actual  api . ChatResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  json . NewDecoder ( w . Body ) . Decode ( & actual ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . Model  !=  "test"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected model test, got %s" ,  actual . Model ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! actual . Done  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done true, got false" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . DoneReason  !=  "load"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done reason load, got %s" ,  actual . DoneReason ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									checkChatResponse  :=  func ( t  * testing . T ,  body  io . Reader ,  model ,  content  string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Helper ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  actual  api . ChatResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  json . NewDecoder ( body ) . Decode ( & actual ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . Model  !=  model  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected model test, got %s" ,  actual . Model ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! actual . Done  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done false, got true" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . DoneReason  !=  "stop"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done reason stop, got %s" ,  actual . DoneReason ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( actual . Message ,  api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Role :     "assistant" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Content :  content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . PromptEvalCount  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected prompt eval count > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . PromptEvalDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected prompt eval duration > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . EvalCount  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected eval count > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . EvalDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected eval duration > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . LoadDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected load duration > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . TotalDuration  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "expected total duration > 0, got 0" ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock . CompletionResponse . Content  =  "Hi!" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "messages" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "Hello!" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "user: Hello!\n" ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkChatResponse ( t ,  w . Body ,  "test" ,  "Hi!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  =  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Model :   "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										From :    "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										System :  "You are a helpful assistant." , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "messages with model system" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "Hello!" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "system: You are a helpful assistant.\nuser: Hello!\n" ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkChatResponse ( t ,  w . Body ,  "test-system" ,  "Hi!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock . CompletionResponse . Content  =  "Abra kadabra!" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "messages with system" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "system" ,  Content :  "You can perform magic tricks." } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "Hello!" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "system: You can perform magic tricks.\nuser: Hello!\n" ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkChatResponse ( t ,  w . Body ,  "test-system" ,  "Abra kadabra!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "messages with interleaved system" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "Hello!" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "assistant" ,  Content :  "I can help you with that." } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "system" ,  Content :  "You can perform magic tricks." } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "Help me write tests." } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "system: You are a helpful assistant.\nuser: Hello!\nassistant: I can help you with that.\nsystem: You can perform magic tricks.\nuser: Help me write tests.\n" ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkChatResponse ( t ,  w . Body ,  "test-system" ,  "Abra kadabra!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "messages with tools (non-streaming)" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "failed to create test-system model: %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tools  :=  [ ] api . Tool { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  "function" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Function :  api . ToolFunction { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Name :         "get_weather" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Description :  "Get the current weather" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Parameters :  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-06 07:46:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Type        string                       ` json:"type" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Defs        any                          ` json:"$defs,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Items       any                          ` json:"items,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Required    [ ] string                     ` json:"required" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Properties  map [ string ] api . ToolProperty  ` json:"properties" ` 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Type :      "object" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Required :  [ ] string { "location" } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-06 07:46:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Properties :  map [ string ] api . ToolProperty { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															"location" :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-08 05:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Type :         api . PropertyType { "string" } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Description :  "The city and state" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															"unit" :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-08 05:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Type :  api . PropertyType { "string" } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-09 06:05:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Enum :  [ ] any { "celsius" ,  "fahrenheit" } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mock . CompletionResponse  =  llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Content :             ` { "name":"get_weather","arguments": { "location":"Seattle, WA","unit":"celsius"}} ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Done :                true , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-04 01:19:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											DoneReason :          llm . DoneReasonStop , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											PromptEvalCount :     1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EvalCount :           1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EvalDuration :        1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										streamRequest  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "What's the weather in Seattle?" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Tools :   tools , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & streamRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  errResp  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Error  string  ` json:"error" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  json . NewDecoder ( w . Body ) . Decode ( & errResp ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Logf ( "Failed to decode error response: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Logf ( "Error response: %s" ,  errResp . Error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  resp  api . ChatResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  json . NewDecoder ( w . Body ) . Decode ( & resp ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  resp . Message . ToolCalls  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Error ( "expected tool calls, got nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedToolCall  :=  api . ToolCall { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Function :  api . ToolCallFunction { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Name :  "get_weather" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Arguments :  api . ToolCallFunctionArguments { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"location" :  "Seattle, WA" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"unit" :      "celsius" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( resp . Message . ToolCalls [ 0 ] ,  expectedToolCall ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "tool call mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "messages with tools (streaming)" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tools  :=  [ ] api . Tool { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Type :  "function" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Function :  api . ToolFunction { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Name :         "get_weather" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Description :  "Get the current weather" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Parameters :  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-06 07:46:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Type        string                       ` json:"type" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Defs        any                          ` json:"$defs,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Items       any                          ` json:"items,omitempty" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Required    [ ] string                     ` json:"required" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Properties  map [ string ] api . ToolProperty  ` json:"properties" ` 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Type :      "object" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Required :  [ ] string { "location" } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-06 07:46:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														Properties :  map [ string ] api . ToolProperty { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															"location" :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-08 05:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Type :         api . PropertyType { "string" } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Description :  "The city and state" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															"unit" :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-08 05:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Type :  api . PropertyType { "string" } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-09 06:05:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																Enum :  [ ] any { "celsius" ,  "fahrenheit" } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Simulate streaming response with multiple chunks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mock . CompletionFn  =  func ( ctx  context . Context ,  r  llm . CompletionRequest ,  fn  func ( r  llm . CompletionResponse ) )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Send chunks with small delays to simulate streaming
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											responses  :=  [ ] llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Content :             ` { "name":"get_ ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Done :                false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PromptEvalCount :     1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Content :             ` weather","arguments": { "location":"Seattle ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Done :                false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PromptEvalCount :     2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Content :             ` , WA","unit":"celsius"}} ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Done :                true , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-04 01:19:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													DoneReason :          llm . DoneReasonStop , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 05:40:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													PromptEvalCount :     3 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  resp  :=  range  responses  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  ctx . Err ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													fn ( resp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													time . Sleep ( 10  *  time . Millisecond )  // Small delay between chunks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Role :  "user" ,  Content :  "What's the weather in Seattle?" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Tools :   tools , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Read and validate the streamed responses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										decoder  :=  json . NewDecoder ( w . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  finalToolCall  api . ToolCall 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  resp  api . ChatResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  decoder . Decode ( & resp ) ;  err  ==  io . EOF  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  resp . Done  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  len ( resp . Message . ToolCalls )  !=  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													t . Errorf ( "expected 1 tool call in final response, got %d" ,  len ( resp . Message . ToolCalls ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												finalToolCall  =  resp . Message . ToolCalls [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedToolCall  :=  api . ToolCall { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Function :  api . ToolCallFunction { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Name :  "get_weather" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Arguments :  api . ToolCallFunctionArguments { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"location" :  "Seattle, WA" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"unit" :      "celsius" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( finalToolCall ,  expectedToolCall ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "final tool call mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestGenerate ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gin . SetMode ( gin . TestMode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock  :=  mockRunner { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CompletionResponse :  llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Done :                true , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-04 01:19:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											DoneReason :          llm . DoneReasonStop , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											PromptEvalCount :     1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EvalCount :           1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EvalDuration :        1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  Server { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sched :  & Scheduler { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pendingReqCh :   make ( chan  * LlmRequest ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishedReqCh :  make ( chan  * LlmRequest ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expiredCh :      make ( chan  * runnerRef ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unloadedCh :     make ( chan  any ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											loaded :         make ( map [ string ] * runnerRef ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newServerFn :    newMockServer ( & mock ) , 
							 
						 
					
						
							
								
									
										
										
										
											2025-10-02 06:12:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											getGpuFn :       getGpuFn , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											getCpuFn :       getCpuFn , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											reschedDelay :   250  *  time . Millisecond , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-30 03:21:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											loadFn :  func ( req  * LlmRequest ,  _  * ggml . GGML ,  _  discover . GpuInfoList ,  _  bool )  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-20 10:11:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// add small delay to simulate loading
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												time . Sleep ( time . Millisecond ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												req . successCh  <-  & runnerRef { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													llama :  & mock , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-30 03:21:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  false 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-09 02:42:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									go  s . sched . Run ( t . Context ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-14 08:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  digest  :=  createBinFile ( t ,  ggml . KV { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"general.architecture" :           "llama" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.block_count" :              uint32 ( 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.context_length" :           uint32 ( 8192 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.embedding_length" :         uint32 ( 4096 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.attention.head_count" :     uint32 ( 32 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"llama.attention.head_count_kv" :  uint32 ( 8 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"tokenizer.ggml.tokens" :          [ ] string { "" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"tokenizer.ggml.scores" :          [ ] float32 { 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"tokenizer.ggml.token_type" :      [ ] int32 { 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 02:20:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ,  [ ] * ggml . Tensor { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ Name :  "token_embd.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_norm.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_down.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_gate.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_up.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.ffn_norm.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_k.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_output.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_q.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "blk.0.attn_v.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ Name :  "output.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  :=  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Model :  "test" , 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Files :  map [ string ] string { "file.gguf" :  digest } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Template :  ` 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{ { -  if  . System  } } System :  { {  . System  } }  { {  end  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  if  . Prompt  } } User :  { {  . Prompt  } }  { {  end  } }  
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ { -  if  . Response  } } Assistant :  { {  . Response  } }  { {  end  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								` ,  
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "missing body" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-19 07:12:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusNotFound  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 404, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-19 07:12:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"model '' not found"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "missing model" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-19 07:12:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusNotFound  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 404, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-19 07:12:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"model '' not found"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . Run ( "missing capabilities generate" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-14 08:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  digest  :=  createBinFile ( t ,  ggml . KV { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											"general.architecture" :  "bert" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"bert.pooling_type" :     uint32 ( 0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-07 02:20:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  [ ] * ggml . Tensor { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Model :   "bert" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Files :   map [ string ] string { "file.gguf" :  digest } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  =  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "bert" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusBadRequest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 400, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"\"bert\" does not support generate"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . Run ( "missing capabilities suffix" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "def add(" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Suffix :  "    return c" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusBadRequest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 400, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-12 07:29:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( w . Body . String ( ) ,  ` { "error":"registry.ollama.ai/library/test:latest does not support insert"} ` ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t . Run ( "load model" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  actual  api . GenerateResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  json . NewDecoder ( w . Body ) . Decode ( & actual ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . Model  !=  "test"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected model test, got %s" ,  actual . Model ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! actual . Done  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done true, got false" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . DoneReason  !=  "load"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done reason load, got %s" ,  actual . DoneReason ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									checkGenerateResponse  :=  func ( t  * testing . T ,  body  io . Reader ,  model ,  content  string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Helper ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  actual  api . GenerateResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  json . NewDecoder ( body ) . Decode ( & actual ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . Model  !=  model  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected model test, got %s" ,  actual . Model ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! actual . Done  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done false, got true" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . DoneReason  !=  "stop"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected done reason stop, got %s" ,  actual . DoneReason ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . Response  !=  content  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected response %s, got %s" ,  content ,  actual . Response ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . Context  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected context not nil" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . PromptEvalCount  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected prompt eval count > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . PromptEvalDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected prompt eval duration > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . EvalCount  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected eval count > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . EvalDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected eval duration > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . LoadDuration  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected load duration > 0, got 0" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actual . TotalDuration  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "expected total duration > 0, got 0" ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock . CompletionResponse . Content  =  "Hi!" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "prompt" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "Hello!" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "User: Hello! " ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkGenerateResponse ( t ,  w . Body ,  "test" ,  "Hi!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  =  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Model :   "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										From :    "test" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										System :  "You are a helpful assistant." , 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "prompt with model system" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "Hello!" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "System: You are a helpful assistant. User: Hello! " ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkGenerateResponse ( t ,  w . Body ,  "test-system" ,  "Hi!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock . CompletionResponse . Content  =  "Abra kadabra!" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "prompt with system" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "Hello!" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											System :  "You can perform magic tricks." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "System: You can perform magic tricks. User: Hello! " ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkGenerateResponse ( t ,  w . Body ,  "test-system" ,  "Abra kadabra!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "prompt with template" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "Help me write tests." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											System :  "You can perform magic tricks." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Template :  ` { { -  if  . System  } } { {  . System  } }  { {  end  } } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  if  . Prompt  } } # # #  USER  { {  . Prompt  } }  { {  end  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  if  . Response  } } # # #  ASSISTANT  { {  . Response  } }  { {  end  } } ` ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "You can perform magic tricks. ### USER Help me write tests. " ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkGenerateResponse ( t ,  w . Body ,  "test-system" ,  "Abra kadabra!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 10:36:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w  =  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Model :  "test-suffix" , 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Template :  ` { { -  if  . Suffix  } } < PRE >  { {  . Prompt  } }  < SUF > { {  . Suffix  } }  < MID > 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ { -  else  } } { {  . Prompt  } }  
						 
					
						
							
								
									
										
										
										
											2025-01-01 10:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{ { -  end  } } ` ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										From :  "test" , 
							 
						 
					
						
							
								
									
										
										
										
											2024-06-21 10:13:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "prompt with suffix" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test-suffix" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "def add(" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Suffix :  "    return c" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "<PRE> def add( <SUF>    return c <MID>" ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "prompt without suffix" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test-suffix" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "def add(" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "def add(" ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-14 08:46:24 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t . Run ( "raw" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . GenerateHandler ,  api . GenerateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :   "test-system" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prompt :  "Help me write tests." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Raw :     true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  diff  :=  cmp . Diff ( mock . CompletionRequest . Prompt ,  "Help me write tests." ) ;  diff  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "mismatch (-got +want):\n%s" ,  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2025-08-23 03:00:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestChatWithPromptEndingInThinkTag ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gin . SetMode ( gin . TestMode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Helper to create a standard thinking test setup
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									setupThinkingTest  :=  func ( t  * testing . T )  ( * mockRunner ,  * Server )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mock  :=  & mockRunner { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CompletionResponse :  llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Done :                true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DoneReason :          llm . DoneReasonStop , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PromptEvalCount :     1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EvalCount :           1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EvalDuration :        1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  & Server { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sched :  & Scheduler { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pendingReqCh :   make ( chan  * LlmRequest ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												finishedReqCh :  make ( chan  * LlmRequest ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												expiredCh :      make ( chan  * runnerRef ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												unloadedCh :     make ( chan  any ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												loaded :         make ( map [ string ] * runnerRef ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												newServerFn :    newMockServer ( mock ) , 
							 
						 
					
						
							
								
									
										
										
										
											2025-10-02 06:12:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getGpuFn :       getGpuFn , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getCpuFn :       getCpuFn , 
							 
						 
					
						
							
								
									
										
										
										
											2025-08-23 03:00:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												reschedDelay :   250  *  time . Millisecond , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												loadFn :  func ( req  * LlmRequest ,  _  * ggml . GGML ,  _  discover . GpuInfoList ,  _  bool )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													time . Sleep ( time . Millisecond ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req . successCh  <-  & runnerRef { llama :  mock } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  s . sched . Run ( t . Context ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Create a model with thinking support
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_ ,  digest  :=  createBinFile ( t ,  ggml . KV { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"general.architecture" :           "llama" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"llama.block_count" :              uint32 ( 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"llama.context_length" :           uint32 ( 8192 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"llama.embedding_length" :         uint32 ( 4096 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"llama.attention.head_count" :     uint32 ( 32 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"llama.attention.head_count_kv" :  uint32 ( 8 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"tokenizer.ggml.tokens" :          [ ] string { "" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"tokenizer.ggml.scores" :          [ ] float32 { 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"tokenizer.ggml.token_type" :      [ ] int32 { 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  [ ] * ggml . Tensor { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "token_embd.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.attn_norm.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.ffn_down.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.ffn_gate.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.ffn_up.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.ffn_norm.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.attn_k.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.attn_output.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.attn_q.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "blk.0.attn_v.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											{ Name :  "output.weight" ,  Shape :  [ ] uint64 { 1 } ,  WriterTo :  bytes . NewReader ( make ( [ ] byte ,  4 ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Create model with thinking template that adds <think> at the end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . CreateHandler ,  api . CreateRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :  "test-thinking" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Files :  map [ string ] string { "file.gguf" :  digest } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Template :  ` { { -  range  . Messages  } } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ { -  if  eq  . Role  "user"  } } user :  { {  . Content  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ {  else  if  eq  . Role  "assistant"  } } assistant :  { {  if  . Thinking  } } < think > { {  . Thinking  } } < / think > { {  end  } } { {  . Content  } }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{ {  end  } } { {  end  } } < think > ` ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :  & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  mock ,  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mock ,  s  :=  setupThinkingTest ( t ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Helper to test chat responses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testChatRequest  :=  func ( t  * testing . T ,  name  string ,  userContent  string ,  modelResponse  string ,  expectedThinking  string ,  expectedContent  string ,  think  bool )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Run ( name ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mock . CompletionResponse  =  llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Content :             modelResponse , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Done :                true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DoneReason :          llm . DoneReasonStop , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PromptEvalCount :     1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PromptEvalDuration :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EvalCount :           1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EvalDuration :        1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mock . CompletionFn  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											streamRequest  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req  :=  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Model :  "test-thinking" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Messages :  [ ] api . Message { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													{ Role :  "user" ,  Content :  userContent } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Stream :  & streamRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  think  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req . Think  =  & api . ThinkValue { Value :  think } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											w  :=  createRequest ( t ,  s . ChatHandler ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  resp  api . ChatResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  json . NewDecoder ( w . Body ) . Decode ( & resp ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  resp . Message . Thinking  !=  expectedThinking  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "expected thinking %q, got %q" ,  expectedThinking ,  resp . Message . Thinking ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  resp . Message . Content  !=  expectedContent  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "expected content %q, got %q" ,  expectedContent ,  resp . Message . Content ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Test cases - Note: Template adds <think> at the end, and leading whitespace after <think> is eaten by the parser
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testChatRequest ( t ,  "basic thinking response" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Help me solve this problem" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Let me think about this step by step... </think> The answer is 42." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Let me think about this step by step... " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"The answer is 42." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testChatRequest ( t ,  "thinking with multiple sentences" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Explain quantum computing" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" First, I need to understand the basics. Quantum bits can be in superposition. </think> Quantum computing uses quantum mechanics principles." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"First, I need to understand the basics. Quantum bits can be in superposition. " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Quantum computing uses quantum mechanics principles." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testChatRequest ( t ,  "no thinking content" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"What is 2+2?" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"</think> The answer is 4." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"The answer is 4." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testChatRequest ( t ,  "thinking disabled but template still adds think tag" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Simple question" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" My thoughts </think> The answer." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" My thoughts </think> The answer." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Test streaming response with template-added <think>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . Run ( "streaming with thinking" ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mock . CompletionFn  =  func ( ctx  context . Context ,  r  llm . CompletionRequest ,  fn  func ( r  llm . CompletionResponse ) )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Verify the prompt ends with <think> due to template
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! strings . HasSuffix ( r . Prompt ,  "<think>" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "expected prompt to end with <think>, got: %q" ,  r . Prompt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Simulate streaming chunks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											responses  :=  [ ] llm . CompletionResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Content :  " I need to consider" ,  Done :  false ,  PromptEvalCount :  1 ,  PromptEvalDuration :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Content :  " multiple factors here..." ,  Done :  false ,  PromptEvalCount :  1 ,  PromptEvalDuration :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Content :  " </think> Based on my analysis," ,  Done :  false ,  PromptEvalCount :  1 ,  PromptEvalDuration :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ Content :  " the solution is straightforward." ,  Done :  true ,  DoneReason :  llm . DoneReasonStop ,  PromptEvalCount :  1 ,  PromptEvalDuration :  1 ,  EvalCount :  1 ,  EvalDuration :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  resp  :=  range  responses  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  ctx . Err ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													fn ( resp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													time . Sleep ( 10  *  time . Millisecond ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										think  :=  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w  :=  createRequest ( t ,  s . ChatHandler ,  api . ChatRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Model :     "test-thinking" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Messages :  [ ] api . Message { { Role :  "user" ,  Content :  "Analyze this complex problem" } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Think :     & api . ThinkValue { Value :  think } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Stream :    & stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "expected status 200, got %d" ,  w . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Parse streaming responses
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										decoder  :=  json . NewDecoder ( w . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  allThinking ,  allContent  strings . Builder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  resp  api . ChatResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  decoder . Decode ( & resp ) ;  err  ==  io . EOF  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allThinking . WriteString ( resp . Message . Thinking ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											allContent . WriteString ( resp . Message . Content ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Note: Leading whitespace after <think> is eaten by the parser
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  got  :=  allThinking . String ( ) ;  got  !=  "I need to consider multiple factors here... "  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected thinking %q, got %q" ,  "I need to consider multiple factors here... " ,  got ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  got  :=  allContent . String ( ) ;  got  !=  "Based on my analysis, the solution is straightforward."  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "expected content %q, got %q" ,  "Based on my analysis, the solution is straightforward." ,  got ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}