char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
566059a26
char/aliceai-t5-moe
1import argparse 2import json 3import requests 4import logging 5import sys 6 7handler = logging .StreamHandler (sys .stdout ) 8handler .terminator = "" # ← no newline 9logging .basicConfig (level = logging .INFO ,format = '%(message)s' ,handlers = [handler ]) 10logger = logging .getLogger ("server-test-model" ) 11 12 13def run_query (url ,messages ,tools = None ,stream = False ,tool_choice = None ): 14payload = { 15"messages" :messages , 16"stream" :stream , 17"max_tokens" :5000 , 18 } 19if tools : 20payload ["tools" ]= tools 21if tool_choice : 22payload ["tool_choice" ]= tool_choice 23 24try : 25response = requests .post (url ,json = payload ,stream = stream ) 26response .raise_for_status () 27except requests .exceptions .RequestException as e : 28if e .response is not None : 29logger .info (f"Response error: { e } for { e . response . content } \n" ) 30else : 31logger .info (f"Error connecting to server: { e } \n" ) 32return None 33 34full_content = "" 35reasoning_content = "" 36tool_calls = [] 37 38if stream : 39logger .info (f"--- Streaming response (Tools: { bool ( tools ) } ) ---\n" ) 40for line in response .iter_lines (): 41if line : 42decoded_line = line .decode ("utf-8" ) 43if decoded_line .startswith ("data: " ): 44data_str = decoded_line [6 :] 45if data_str == "[DONE]" : 46break 47try : 48data = json .loads (data_str ) 49if "choices" in data and len (data ["choices" ])> 0 : 50delta = data ["choices" ][0 ].get ("delta" , {}) 51 52# Content 53content_chunk = delta .get ("content" ,"" ) 54if content_chunk : 55full_content += content_chunk 56logger .info (content_chunk ) 57 58# Reasoning 59reasoning_chunk = delta .get ("reasoning_content" ,"" ) 60if reasoning_chunk : 61reasoning_content += reasoning_chunk 62logger .info (f"\x1B[3m { reasoning_chunk } \x1B[0m" ) 63 64# Tool calls 65if "tool_calls" in delta : 66for tc in delta ["tool_calls" ]: 67index = tc .get ("index" ) 68if index is not None : 69while len (tool_calls )<= index : 70# Using "function" as type default but could be flexible 71tool_calls .append ( 72 { 73"id" :"" , 74"type" :"function" , 75"function" : { 76"name" :"" , 77"arguments" :"" , 78 }, 79 } 80 ) 81 82if "id" in tc : 83tool_calls [index ]["id" ]+= tc ["id" ] 84if "function" in tc : 85if "name" in tc ["function" ]: 86tool_calls [index ]["function" ][ 87"name" 88 ]+= tc ["function" ]["name" ] 89if "arguments" in tc ["function" ]: 90tool_calls [index ]["function" ][ 91"arguments" 92 ]+= tc ["function" ]["arguments" ] 93 94except json .JSONDecodeError : 95logger .info (f"Failed to decode JSON: { data_str } \n" ) 96logger .info ("\n--- End of Stream ---\n" ) 97else : 98logger .info (f"--- Non-streaming response (Tools: { bool ( tools ) } ) ---\n" ) 99data = response .json () 100if "choices" in data and len (data ["choices" ])> 0 : 101message = data ["choices" ][0 ].get ("message" , {}) 102full_content = message .get ("content" ,"" ) 103reasoning_content = message .get ("reasoning_content" ,"" ) 104tool_calls = message .get ("tool_calls" , []) 105logger .info (full_content ) 106logger .info ("--- End of Response ---\n" ) 107 108return { 109"content" :full_content , 110"reasoning_content" :reasoning_content , 111"tool_calls" :tool_calls , 112 } 113 114 115def test_chat (url ,stream ): 116logger .info (f"\n=== Testing Chat (Stream= { stream } ) ===\n" ) 117messages = [{"role" :"user" ,"content" :"What is the capital of France?" }] 118result = run_query (url ,messages ,stream = stream ) 119 120if result : 121if result ["content" ]: 122logger .info ("PASS: Output received.\n" ) 123else : 124logger .info ("WARN: No content received (valid if strict tool call, but unexpected here).\n" ) 125 126if result .get ("reasoning_content" ): 127logger .info (f"INFO: Reasoning content detected ( { len ( result [ 'reasoning_content' ]) } chars).\n" ) 128else : 129logger .info ("INFO: No reasoning content detected (Standard model behavior).\n" ) 130else : 131logger .info ("FAIL: No result.\n" ) 132 133 134def test_tool_call (url ,stream ): 135logger .info (f"\n=== Testing Tool Call (Stream= { stream } ) ===\n" ) 136messages = [ 137 { 138"role" :"user" , 139"content" :"What is the weather in London? Please use the get_weather tool." , 140 } 141 ] 142tools = [ 143 { 144"type" :"function" , 145"function" : { 146"name" :"get_weather" , 147"description" :"Get the current weather in a given location" , 148"parameters" : { 149"type" :"object" , 150"properties" : { 151"location" : { 152"type" :"string" , 153"description" :"The city and state, e.g. San Francisco, CA" , 154 }, 155"unit" : {"type" :"string" ,"enum" : ["celsius" ,"fahrenheit" ]}, 156 }, 157"required" : ["location" ], 158 }, 159 }, 160 } 161 ] 162 163result = run_query (url ,messages ,tools = tools ,tool_choice = "auto" ,stream = stream ) 164 165if result : 166tcs = result .get ("tool_calls" ) 167if tcs and len (tcs )> 0 : 168logger .info ("PASS: Tool calls detected." ) 169for tc in tcs : 170func = tc .get ("function" , {}) 171logger .info (f" Tool: { func . get ( 'name' ) } , Args: { func . get ( 'arguments' ) } \n" ) 172else : 173logger .info (f"FAIL: No tool calls. Content: { result [ 'content' ] } \n" ) 174 175if result .get ("reasoning_content" ): 176logger .info ( 177f"INFO: Reasoning content detected during tool call ( { len ( result [ 'reasoning_content' ]) } chars).\n" 178 ) 179else : 180logger .info ("FAIL: Query failed.\n" ) 181 182 183def main (): 184parser = argparse .ArgumentParser (description = "Test llama-server functionality." ) 185parser .add_argument ("--host" ,default = "localhost" ,help = "Server host" ) 186parser .add_argument ("--port" ,default = 8080 ,type = int ,help = "Server port" ) 187args = parser .parse_args () 188 189base_url = f"http:// { args . host } : { args . port } /v1/chat/completions" 190logger .info (f"Testing server at { base_url } \n" ) 191 192# Non-streaming tests 193test_chat (base_url ,stream = False ) 194test_tool_call (base_url ,stream = False ) 195 196# Streaming tests 197test_chat (base_url ,stream = True ) 198test_tool_call (base_url ,stream = True ) 199 200 201if __name__ == "__main__" : 202main ()