Skip to content

Commit 66691ed

Browse files
committed
a first working version integrated tree_sitter with python parser code
1 parent 093847a commit 66691ed

File tree

2 files changed

+211
-1
lines changed

2 files changed

+211
-1
lines changed

examples/server/utils.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ static json format_final_response_oaicompat(const json & request, json result, c
828828
if (parsed_content.empty()) {
829829
choices = json::array({json{{"finish_reason", finish_reason},
830830
{"index", 0},
831-
{"message", json{{"content", content},
831+
{"message", json{{"content", parsed_content},
832832
{"role", "assistant"}}}}});
833833
} else {
834834
std::vector<json> oai_format_tool_calls;

test_llamacpp.ipynb

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
" )\n",
5858
" return completion.choices[0]\n",
5959
" except Exception as e:\n",
60+
<<<<<<< HEAD
6061
" print(e)\n",
6162
"\n",
6263
"\n",
@@ -140,6 +141,37 @@
140141
" 'required': []\n",
141142
" }\n",
142143
" }\n",
144+
=======
145+
" print(e, model, prompt)\n"
146+
]
147+
},
148+
{
149+
"cell_type": "code",
150+
"execution_count": 163,
151+
"metadata": {},
152+
"outputs": [
153+
{
154+
"name": "stdout",
155+
"output_type": "stream",
156+
"text": [
157+
" <<functions>>[orderUmbrella(brand_name=\"Patagonia\")]\n"
158+
]
159+
}
160+
],
161+
"source": [
162+
"system_prompt = \"You are a helpful assistant.\"\n",
163+
"functions = [\n",
164+
" {\n",
165+
" \"type\": \"function\",\n",
166+
" \"function\": {\n",
167+
" \"name\": \"getCurrentWeather\",\n",
168+
" \"description\": \"Get the weather in location\",\n",
169+
" \"parameters\": {\n",
170+
" \"type\": \"object\",\n",
171+
" \"properties\": {\n",
172+
" \"location\": {\"type\": \"string\", \"description\": \"The city and state e.g. San Francisco, CA\"},\n",
173+
" \"unit\": {\"type\": \"string\", \"enum\": [\"c\", \"f\"]}\n",
174+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
143175
" },\n",
144176
" {\n",
145177
" 'type': 'function',\n",
@@ -281,6 +313,7 @@
281313
},
282314
{
283315
"cell_type": "code",
316+
<<<<<<< HEAD
284317
"execution_count": 4,
285318
"metadata": {},
286319
"outputs": [],
@@ -293,12 +326,16 @@
293326
{
294327
"cell_type": "code",
295328
"execution_count": 5,
329+
=======
330+
"execution_count": 177,
331+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
296332
"metadata": {},
297333
"outputs": [
298334
{
299335
"name": "stdout",
300336
"output_type": "stream",
301337
"text": [
338+
<<<<<<< HEAD
302339
"Pointing to URL: http://localhost:8019/v1/\n",
303340
"\n",
304341
"[AI calling functions]:\n",
@@ -311,28 +348,89 @@
311348
"\n",
312349
"[AI response]:\n",
313350
" The distance between San Francisco and Cupertino by driving is 50 miles and 100 miles from Cupertino to San Francisco. When traveling by air, the distance is 150 miles from San Francisco to Cupertino and 200 miles from Cupertino to San Francisco.\n"
351+
=======
352+
" <<functions>>[get_stock_fundermentals(symbol=\"TSLA\")]\n",
353+
"<<functions>>[get_stock_fundermentals(symbol=\"GOOG\")]\n"
354+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
314355
]
315356
}
316357
],
317358
"source": [
359+
<<<<<<< HEAD
318360
"\n",
319361
"get_mistral_rubra_response = partial(get_oai_response, api_key=local_api_key, base_url=local_base_url)\n",
320362
"\n",
321363
"user_query = \"What is the distance between San Francisco and Cupertino by driving and by air from both directions?\"\n",
322364
"# user_query = \"What is four plus six? What is the result of that plus 2? Take the result and multiply by 5 and then divide by two\"\n",
323365
"# user_query = \"what's the distance between SF and NYC? Use the result value to multiply by 8, and then divide by 2, and then minus 30\"\n",
324366
"msgs = run_completion(get_mistral_rubra_response, user_query)\n"
367+
=======
368+
"system_prompt = \"You are a helpful assistant.\"\n",
369+
"functions = [\n",
370+
" {\"function\":\n",
371+
" {\n",
372+
" \"name\": \"get_stock_fundermentals\",\n",
373+
" \"description\": \"Get the stock fundermentals data\",\n",
374+
" \"parameters\": {\n",
375+
" \"type\": \"object\",\n",
376+
" \"properties\": {\n",
377+
" \"symbol\": {\n",
378+
" \"type\": \"string\",\n",
379+
" \"description\": \"The stock symbol, e.g. AAPL, GOOG\"\n",
380+
" }\n",
381+
" },\n",
382+
" \"required\": [\n",
383+
" \"symbol\"\n",
384+
" ]\n",
385+
" }\n",
386+
" }},\n",
387+
" {\"function\":{\n",
388+
" \"name\": \"check_word_anagram\",\n",
389+
" \"description\": \"Check if two words are anagrams of each other\",\n",
390+
" \"parameters\": {\n",
391+
" \"type\": \"object\",\n",
392+
" \"properties\": {\n",
393+
" \"word1\": {\n",
394+
" \"type\": \"string\",\n",
395+
" \"description\": \"The first word\"\n",
396+
" },\n",
397+
" \"word2\": {\n",
398+
" \"type\": \"string\",\n",
399+
" \"description\": \"The second word\"\n",
400+
" }\n",
401+
" },\n",
402+
" \"required\": [\n",
403+
" \"word1\",\n",
404+
" \"word2\"\n",
405+
" ]\n",
406+
" }\n",
407+
" }}\n",
408+
"]\n",
409+
"\n",
410+
"user_query = \"What's the stock fundementals of Tesla and google\"\n",
411+
"\n",
412+
"# \n",
413+
"# msgs = [{\"role\": \"system\", \"content\":system_prompt} ,{\"role\": \"user\", \"content\": user_query}, {\"role\": \"function\", \"content\": '<<functions>>[get_stock_price(symbol=\"TSLA\")], <<functions>>[get_stock_price(symbol=\"GOOG\")]'}, {\"role\": \"observation\", \"content\": \"{'symbol': 'TSLA', 'company_name': 'Tesla, Inc.', 'sector': 'Consumer Cyclical', 'industry': 'Auto Manufacturers', 'market_cap': 611384164352, 'pe_ratio': 49.604652, 'pb_ratio': 9.762013, 'dividend_yield': None, 'eps': 4.3, 'beta': 2.427, '52_week_high': 299.29, '52_week_low': 152.37}}\"}]\n",
414+
"msgs = [{\"role\": \"system\", \"content\":system_prompt} ,{\"role\": \"user\", \"content\": user_query},]\n",
415+
"res = get_mistral_rubra_response(user_query, \"mistral_rubra\", functions=functions, msgs=msgs)\n",
416+
"print(res.message.content)"
417+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
325418
]
326419
},
327420
{
328421
"cell_type": "code",
422+
<<<<<<< HEAD
329423
"execution_count": 8,
424+
=======
425+
"execution_count": 183,
426+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
330427
"metadata": {},
331428
"outputs": [
332429
{
333430
"name": "stdout",
334431
"output_type": "stream",
335432
"text": [
433+
<<<<<<< HEAD
336434
"Pointing to URL: http://localhost:8019/v1/\n",
337435
"\n",
338436
"[AI calling functions]:\n",
@@ -343,10 +441,15 @@
343441
"\n",
344442
"[AI response]:\n",
345443
" Your order for 3 umbrellas has been placed, and the total price is 10 dollars. The generated password is 96ddefe8.\n"
444+
=======
445+
"<ast.List object at 0x105649390>\n",
446+
"[('get_current_weather', [], {'location': 'Boston, MA', 'api_key': 123456789, 'unit': 'fahrenheit'}), ('func', ['cde'], {'x': 1, 'b': '2', 'c': [1, 2, {'a': 1, 'b': 2}]})]\n"
447+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
346448
]
347449
}
348450
],
349451
"source": [
452+
<<<<<<< HEAD
350453
"user_query2 = \"now order 3 umbrellas for me and generate a password of length 8\"\n",
351454
"msgs = run_completion(get_mistral_rubra_response, user_query2, msgs)"
352455
]
@@ -356,17 +459,64 @@
356459
"metadata": {},
357460
"source": [
358461
"## Simple Math Chaining"
462+
=======
463+
"import ast\n",
464+
"\n",
465+
"input_str = \"[get_current_weather(location='Boston, MA', api_key=123456789, unit='fahrenheit'), func('cde', x=1, b='2', c=[1, 2, {'a': 1, 'b': 2}])]\"\n",
466+
"\n",
467+
"# Parse the string into an AST\n",
468+
"parsed_ast = ast.parse(input_str, mode='eval')\n",
469+
"\n",
470+
"# Function to convert an AST node to a Python object\n",
471+
"def ast_node_to_object(node):\n",
472+
" if isinstance(node, ast.Constant):\n",
473+
" return node.value\n",
474+
" elif isinstance(node, ast.List):\n",
475+
" return [ast_node_to_object(n) for n in node.elts]\n",
476+
" elif isinstance(node, ast.Dict):\n",
477+
" return {ast_node_to_object(key): ast_node_to_object(value) for key, value in zip(node.keys, node.values)}\n",
478+
" elif isinstance(node, ast.Tuple):\n",
479+
" return tuple(ast_node_to_object(n) for n in node.elts)\n",
480+
" # Add more cases here as needed\n",
481+
" return None\n",
482+
"\n",
483+
"def find_calls(node):\n",
484+
" calls = []\n",
485+
" if isinstance(node, ast.Call): # If it's a function call\n",
486+
" calls.append(node)\n",
487+
" for child in ast.iter_child_nodes(node):\n",
488+
" calls.extend(find_calls(child))\n",
489+
" return calls\n",
490+
"\n",
491+
"# Extract all function call nodes\n",
492+
"calls = find_calls(parsed_ast.body)\n",
493+
"\n",
494+
"functions = []\n",
495+
"for call in calls:\n",
496+
" if isinstance(call.func, ast.Name): # Ensure it's a named function\n",
497+
" function_name = call.func.id\n",
498+
" args = [ast_node_to_object(arg) for arg in call.args] # Convert all positional arguments\n",
499+
" kwargs = {kw.arg: ast_node_to_object(kw.value) for kw in call.keywords} # Convert all keyword arguments\n",
500+
" functions.append((function_name, args, kwargs))\n",
501+
"\n",
502+
"print(functions)\n"
503+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
359504
]
360505
},
361506
{
362507
"cell_type": "code",
508+
<<<<<<< HEAD
363509
"execution_count": 9,
510+
=======
511+
"execution_count": 4,
512+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
364513
"metadata": {},
365514
"outputs": [
366515
{
367516
"name": "stdout",
368517
"output_type": "stream",
369518
"text": [
519+
<<<<<<< HEAD
370520
"Pointing to URL: http://localhost:8019/v1/\n",
371521
"\n",
372522
"[AI calling functions]:\n",
@@ -388,10 +538,14 @@
388538
"Cell \u001b[0;32mIn[3], line 77\u001b[0m, in \u001b[0;36minsert_tool_response\u001b[0;34m(res, msgs)\u001b[0m\n\u001b[1;32m 72\u001b[0m msgs\u001b[38;5;241m.\u001b[39mappend({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrole\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtool\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtool_call_id\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mstr\u001b[39m(assistant_message\u001b[38;5;241m.\u001b[39mtool_calls[i]\u001b[38;5;241m.\u001b[39mid), \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m: assistant_message\u001b[38;5;241m.\u001b[39mtool_calls[i]\u001b[38;5;241m.\u001b[39mfunction\u001b[38;5;241m.\u001b[39mname, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mOrder placed. the price is \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m(i\u001b[38;5;241m+\u001b[39m\u001b[38;5;241m1\u001b[39m)\u001b[38;5;250m \u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;250m \u001b[39m\u001b[38;5;241m10\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m dollars.\u001b[39m\u001b[38;5;124m\"\u001b[39m})\n\u001b[1;32m 73\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m tool_call\u001b[38;5;241m.\u001b[39mfunction\u001b[38;5;241m.\u001b[39mname \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124maddition\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 74\u001b[0m msgs\u001b[38;5;241m.\u001b[39mappend({\n\u001b[1;32m 75\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrole\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtool\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 76\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124maddition\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m---> 77\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtool_call\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunction\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marguments\u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m 78\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtool_call_id\u001b[39m\u001b[38;5;124m\"\u001b[39m: tool_call\u001b[38;5;241m.\u001b[39mid\n\u001b[1;32m 79\u001b[0m })\n\u001b[1;32m 80\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m tool_call\u001b[38;5;241m.\u001b[39mfunction\u001b[38;5;241m.\u001b[39mname \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msubtraction\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 81\u001b[0m msgs\u001b[38;5;241m.\u001b[39mappend({\n\u001b[1;32m 82\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrole\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtool\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 83\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msubtraction\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 84\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m: sub(tool_call\u001b[38;5;241m.\u001b[39mfunction\u001b[38;5;241m.\u001b[39marguments),\n\u001b[1;32m 85\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtool_call_id\u001b[39m\u001b[38;5;124m\"\u001b[39m: tool_call\u001b[38;5;241m.\u001b[39mid\n\u001b[1;32m 86\u001b[0m })\n",
389539
"Cell \u001b[0;32mIn[3], line 8\u001b[0m, in \u001b[0;36madd\u001b[0;34m(args)\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21madd\u001b[39m(args: \u001b[38;5;28mstr\u001b[39m):\n\u001b[1;32m 7\u001b[0m args \u001b[38;5;241m=\u001b[39m json\u001b[38;5;241m.\u001b[39mloads(args)\n\u001b[0;32m----> 8\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43ma\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mfloat\u001b[39m(args[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m]))\n",
390540
"\u001b[0;31mValueError\u001b[0m: could not convert string to float: 'result'"
541+
=======
542+
"[('get_current_weather', [], {'location': 'Boston, MA', 'api_key': 123456789, 'unit': 'fahrenheit'}), ('func', ['cde'], {'x': 1, 'b': '2', 'c': ['func_nested(1, 2)', {'a': \"func_deep('value')\"}]})]\n"
543+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
391544
]
392545
}
393546
],
394547
"source": [
548+
<<<<<<< HEAD
395549
"user_query3 = \"User tool to help me : What is four plus six? What is the result of that plus 2? Take the result and multiply by 5 and then divide by two\"\n",
396550
"msgs = run_completion(get_mistral_rubra_response, user_query3, msgs)"
397551
]
@@ -402,6 +556,62 @@
402556
"metadata": {},
403557
"outputs": [],
404558
"source": []
559+
=======
560+
"import ast\n",
561+
"\n",
562+
"input_str = \"[get_current_weather(location='Boston, MA', api_key=123456789, unit='fahrenheit'), func('cde', x=1, b='2', c=[func_nested(1, 2), {'a': func_deep('value')}])]\"\n",
563+
"\n",
564+
"def ast_node_to_object(node):\n",
565+
" if isinstance(node, ast.Constant):\n",
566+
" return node.value\n",
567+
" elif isinstance(node, ast.List):\n",
568+
" return [ast_node_to_object(n) for n in node.elts]\n",
569+
" elif isinstance(node, ast.Dict):\n",
570+
" return {ast_node_to_object(key): ast_node_to_object(value) for key, value in zip(node.keys, node.values)}\n",
571+
" elif isinstance(node, ast.Tuple):\n",
572+
" return tuple(ast_node_to_object(n) for n in node.elts)\n",
573+
" elif isinstance(node, ast.Call):\n",
574+
" return ast.unparse(node)\n",
575+
" # Handle function calls: convert to a representation with the function name and arguments\n",
576+
" # func_name = ast_node_to_object(node.func) # Get the function name\n",
577+
" # args = [ast_node_to_object(arg) for arg in node.args] # Convert all positional arguments\n",
578+
" # kwargs = {kw.arg: ast_node_to_object(kw.value) for kw in node.keywords} # Convert all keyword arguments\n",
579+
" # return {\"function\": func_name, \"args\": args, \"kwargs\": kwargs}\n",
580+
" elif isinstance(node, ast.Name):\n",
581+
" return node.id # Return the identifier name\n",
582+
" # Add more cases here as needed\n",
583+
" return None\n",
584+
"\n",
585+
"# Parse the string into an AST\n",
586+
"parsed_ast = ast.parse(input_str, mode='eval')\n",
587+
"\n",
588+
"# Function to find only the top-level Call nodes\n",
589+
"def find_top_level_calls(node):\n",
590+
" calls = []\n",
591+
" if isinstance(node, ast.Call): # If it's a function call\n",
592+
" calls.append(node)\n",
593+
" # Do not descend into child nodes to ensure we're only capturing top-level calls\n",
594+
" return calls\n",
595+
" for child in ast.iter_child_nodes(node):\n",
596+
" # Recursively find calls without going into nested calls\n",
597+
" calls.extend(find_top_level_calls(child))\n",
598+
" return calls\n",
599+
"\n",
600+
"# Extract all top-level function call nodes\n",
601+
"top_level_calls = find_top_level_calls(parsed_ast.body)\n",
602+
"\n",
603+
"# Process each call node to get the details you want\n",
604+
"functions = []\n",
605+
"for call in top_level_calls:\n",
606+
" if isinstance(call.func, ast.Name): # Ensure it's a named function\n",
607+
" function_name = call.func.id\n",
608+
" args = [ast_node_to_object(arg) for arg in call.args] # Convert all positional arguments\n",
609+
" kwargs = {kw.arg: ast_node_to_object(kw.value) for kw in call.keywords} # Convert all keyword arguments\n",
610+
" functions.append((function_name, args, kwargs))\n",
611+
"\n",
612+
"print(functions)\n"
613+
]
614+
>>>>>>> ba3724d (a first working version integrated tree_sitter with python parser code)
405615
}
406616
],
407617
"metadata": {

0 commit comments

Comments
 (0)