@@ -339,7 +339,7 @@ static json probs_vector_to_json(const llama_context * ctx, const std::vector<co
339
339
//
340
340
341
341
342
- static std::string rubra_format_function_call_str (const std::vector<json> & functions, json & tool_name_map) {
342
+ static std::string rubra_format_python_function_call_str (const std::vector<json> & functions, json & tool_name_map) {
343
343
std::string final_str = " You have access to the following tools:\n " ;
344
344
printf (" rubra_format_function_call_str parsing...\n " );
345
345
json type_mapping = {
@@ -432,6 +432,104 @@ static std::string rubra_format_function_call_str(const std::vector<json> & func
432
432
return final_str;
433
433
}
434
434
435
+
436
+ // Helper function to join strings with a delimiter
437
+ static std::string helper_join (const std::vector<std::string>& elements, const std::string& delimiter) {
438
+ std::string result;
439
+ for (auto it = elements.begin (); it != elements.end (); ++it) {
440
+ if (!result.empty ()) {
441
+ result += delimiter;
442
+ }
443
+ result += *it;
444
+ }
445
+ return result;
446
+ }
447
+
448
+ static std::string rubra_format_typescript_function_call_str (const std::vector<json> &functions, json &tool_name_map) {
449
+ std::string final_str = " You have access to the following tools:\n " ;
450
+ json type_mapping = {
451
+ {" string" , " string" },
452
+ {" integer" , " number" },
453
+ {" number" , " number" },
454
+ {" float" , " number" },
455
+ {" object" , " any" },
456
+ {" array" , " any[]" },
457
+ {" boolean" , " boolean" },
458
+ {" null" , " null" }
459
+ };
460
+
461
+ std::vector<std::string> function_definitions;
462
+ for (const auto &function : functions) {
463
+ const auto &spec = function.contains (" function" ) ? function[" function" ] : function;
464
+ std::string func_name = spec.value (" name" , " " );
465
+ if (func_name.find (' -' ) != std::string::npos) {
466
+ const std::string origin_func_name = func_name;
467
+ std::replace (func_name.begin (), func_name.end (), ' -' , ' _' ); // replace "-" with "_" because - is invalid in typescript func name
468
+ tool_name_map[func_name] = origin_func_name;
469
+ }
470
+
471
+ const std::string description = spec.contains (" description" ) ? spec[" description" ].get <std::string>() : " " ;
472
+ const auto & parameters = spec.contains (" parameters" ) ? spec[" parameters" ].value (" properties" , json ({})) : json ({});
473
+ const auto & required_params = spec.contains (" parameters" ) ? spec[" parameters" ].value (" required" , std::vector<std::string>()) : std::vector<std::string>();
474
+
475
+ std::vector<std::string> func_args;
476
+ std::string docstring = " /**\n * " + description + " \n " ;
477
+
478
+ for (auto it = parameters.begin (); it != parameters.end (); ++it) {
479
+ const std::string param = it.key ();
480
+ const json& details = it.value ();
481
+ std::string json_type = details[" type" ].get <std::string>();
482
+ std::string ts_type = type_mapping.value (json_type, " any" );
483
+ std::string param_description = " " ;
484
+ if (details.count (" description" ) > 0 ) {
485
+ param_description = details[" description" ]; // Assuming the description is the first element
486
+ }
487
+ if (details.count (" enum" ) > 0 ) {
488
+ std::string enum_values;
489
+ for (const std::string val : details[" enum" ]) {
490
+ if (!enum_values.empty ()) {
491
+ enum_values += " or " ;
492
+ }
493
+ enum_values = enum_values+ " \" " + val + " \" " ;
494
+ }
495
+ if (details[" enum" ].size () == 1 ) {
496
+ param_description += " Only Acceptable value is: " + enum_values;
497
+ } else {
498
+ param_description += " Only Acceptable values are: " + enum_values;
499
+ }
500
+ }
501
+ if (param_description.empty ()) {
502
+ param_description = " No description provided." ;
503
+ }
504
+ if (details.contains (" enum" )) {
505
+ ts_type = " string" ; // Enum is treated as string in typescript
506
+ }
507
+ std::string arg_str = param + " : " + ts_type;
508
+ if (find (required_params.begin (), required_params.end (), param) == required_params.end ()) {
509
+ arg_str = param + " ?: " + ts_type;
510
+ docstring += " * @param " + param + " - " + param_description + " \n " ;
511
+ } else {
512
+ docstring += " * @param " + param + " - " + param_description + " \n " ;
513
+ }
514
+ func_args.push_back (arg_str);
515
+ }
516
+ docstring += " */\n " ;
517
+
518
+ std::string func_args_str = helper_join (func_args, " , " );
519
+ std::string function_definition = docstring + " function " + func_name + " (" + func_args_str + " ): any {}" ;
520
+
521
+ function_definitions.push_back (function_definition);
522
+ }
523
+
524
+ for (const auto & def : function_definitions) {
525
+ final_str += def + " \n\n " ;
526
+ }
527
+ final_str += " Use the following format if using tools:\n <<functions>>[toolname1(arg1=value1, arg2=value2, ...), toolname2(arg1=value1, arg2=value2, ...)]" ;
528
+ return final_str;
529
+ }
530
+
531
+
532
+
435
533
static std::string default_tool_formatter (const std::vector<json>& tools) {
436
534
std::string toolText = " " ;
437
535
std::vector<std::string> toolNames;
@@ -493,12 +591,12 @@ static json oaicompat_completion_params_parse(
493
591
494
592
if (body.contains (" tools" ) && !body[" tools" ].empty ()) {
495
593
// function_str = default_tool_formatter(body["tool"]);
496
- function_str = rubra_format_function_call_str (body[" tools" ], tool_name_map);
594
+ function_str = rubra_format_typescript_function_call_str (body[" tools" ], tool_name_map);
497
595
}
498
596
// If 'tool' is not set or empty, check 'functions'
499
597
else if (body.contains (" functions" ) && !body[" functions" ].empty ()) {
500
598
// function_str = default_tool_formatter(body["functions"]);
501
- function_str = rubra_format_function_call_str (body[" functions" ], tool_name_map);
599
+ function_str = rubra_format_typescript_function_call_str (body[" functions" ], tool_name_map);
502
600
}
503
601
printf (" \n =============Formatting Input from OPENAI format...============\n " );
504
602
if (function_str != " " ) {
0 commit comments