MCPcopy Create free account
hub / github.com/RunanywhereAI/RCLI / try_parse_bare_tool_calls

Function try_parse_bare_tool_calls

src/api/rcli_api.cpp:914–984  ·  view source on GitHub ↗

Fallback: detect bare function calls like "func_name(arg=val)" without tool-call tags. Matches against known action names so we don't false-positive on normal text.

Source from the content-addressed store, hash-verified

912// Fallback: detect bare function calls like "func_name(arg=val)" without tool-call tags.
913// Matches against known action names so we don't false-positive on normal text.
914static std::vector<rastack::ToolCall> try_parse_bare_tool_calls(
915 RCLIEngine* engine, const std::string& text)
916{
917 std::vector<rastack::ToolCall> calls;
918 auto all_names = engine->actions.list_actions();
919 for (auto& tool_name : engine->pipeline.tools().list_tool_names())
920 all_names.push_back(tool_name);
921
922 for (const auto& name : all_names) {
923 std::string lower_text = text;
924 for (auto& c : lower_text) c = std::tolower(static_cast<unsigned char>(c));
925 std::string lower_name = name;
926 for (auto& c : lower_name) c = std::tolower(static_cast<unsigned char>(c));
927
928 size_t pos = lower_text.find(lower_name + "(");
929 if (pos == std::string::npos) continue;
930 if (pos > 0 && std::isalnum(static_cast<unsigned char>(text[pos - 1]))) continue;
931
932 size_t paren_open = pos + name.size();
933 int depth = 0;
934 size_t paren_close = std::string::npos;
935 for (size_t i = paren_open; i < text.size(); i++) {
936 if (text[i] == '(') depth++;
937 if (text[i] == ')') { depth--; if (depth == 0) { paren_close = i; break; } }
938 }
939 if (paren_close == std::string::npos) continue;
940
941 std::string params_str = text.substr(paren_open + 1, paren_close - paren_open - 1);
942
943 std::string json = "{";
944 bool first = true;
945 size_t p = 0;
946 while (p < params_str.size()) {
947 while (p < params_str.size() && (params_str[p] == ' ' || params_str[p] == ',')) p++;
948 if (p >= params_str.size()) break;
949
950 auto eq = params_str.find('=', p);
951 if (eq == std::string::npos) break;
952 std::string key = params_str.substr(p, eq - p);
953 while (!key.empty() && key.back() == ' ') key.pop_back();
954 while (!key.empty() && key.front() == ' ') key.erase(key.begin());
955
956 p = eq + 1;
957 while (p < params_str.size() && params_str[p] == ' ') p++;
958 if (p >= params_str.size()) break;
959
960 std::string val;
961 if (params_str[p] == '"' || params_str[p] == '\'') {
962 char q = params_str[p++];
963 while (p < params_str.size() && params_str[p] != q) val += params_str[p++];
964 if (p < params_str.size()) p++;
965 } else {
966 while (p < params_str.size() && params_str[p] != ',' && params_str[p] != ')')
967 val += params_str[p++];
968 while (!val.empty() && val.back() == ' ') val.pop_back();
969 }
970
971 if (!first) json += ", ";

Callers 2

rcli_process_commandFunction · 0.85
rcli_process_and_speakFunction · 0.85

Calls 4

list_actionsMethod · 0.80
list_tool_namesMethod · 0.80
emptyMethod · 0.80
sizeMethod · 0.45

Tested by

no test coverage detected