Skip to content

Commit

Permalink
add a typescript jsonrepair to fix json. This is a temp solution, ide…
Browse files Browse the repository at this point in the history
…ally the jsonrepair code should be written in c++
  • Loading branch information
tybalex committed May 24, 2024
1 parent 2174b0d commit 7511005
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
*package-lock.json
*package.json
*node_modules
*.ipynb
*.o
*.a
Expand Down
85 changes: 83 additions & 2 deletions examples/server/function-call-parser.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include <iostream>
#include <fstream>
#include "json.hpp"
#include <yaml-cpp/yaml.h>
#include <regex>
#include <memory>

using json = nlohmann::ordered_json;
using namespace std;
Expand Down Expand Up @@ -109,6 +112,80 @@ std::string generate_uuid() {
return uuid.str();
}


std::string jsonrepair(const std::string value) {
std::array<char, 128> buffer;
std::string result;
// Ensure the command passed to popen() is null-terminated
string tmpfile_name = generate_uuid() + ".json";
std::ofstream outfile(tmpfile_name);
outfile << value; // Assuming jsonStr contains your JSON string
outfile.close();
string command = "node jsonrepair.ts " + tmpfile_name;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(command.c_str(), "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}


json parse_if_json(const string& value) {
try {
// json repair here
return json::parse(jsonrepair(value));
} catch (const json::parse_error&) {
return value; // Return the original string if parsing fails
}
}


string clean_command_string(const string& command_str) {
string cleaned_command = regex_replace(command_str, regex(R"(\\(?!["\\/bfnrt]|u[a-fA-F0-9]{4}))"), "");
cleaned_command = regex_replace(cleaned_command, regex(R"(\\")"), "\"");

if (cleaned_command.front() == '"' && cleaned_command.back() == '"') {
cleaned_command = cleaned_command.substr(1, cleaned_command.size() - 2);
}
return cleaned_command;
}


json clean_json_strings(const string& input_str) {
try {
// json repair here
string fixed_str = jsonrepair(input_str);
json data = json::parse(fixed_str);

for (auto& [key, value] : data.items()) {
if (value.is_string()) {
string val = value.get<string>();
if (val.front() == '{' || val.front() == '[') {
data[key] = parse_if_json(val);
} else {
data[key] = clean_command_string(val);
}
} else if (value.is_object()) {
for (auto& [k, v] : value.items()) {
if (v.is_string()) {
v = clean_command_string(v.get<string>());
}
}
}
}
return data;
} catch (const json::parse_error& e) {
cout << "Error decoding JSON: " << e.what() << endl;
return nullptr;
}
}




std::vector<json> rubra_fc_json_tool_extractor(const std::string& output_str) {
std::vector<json> result;
std::string str_to_parse;
Expand All @@ -129,11 +206,15 @@ std::vector<json> rubra_fc_json_tool_extractor(const std::string& output_str) {

try {
while (std::getline(stream, line)) {
json fc = json::parse(line);
// json fc = json::parse(line);
json fc = clean_json_strings(line);
if (fc["arguments"].is_string()) {
fc["arguments"] = json::parse(fc["arguments"].get<std::string>());
}
function_call_json.push_back(fc);
if (!fc.is_null()) {
function_call_json.push_back(fc);
}

}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
Expand Down
24 changes: 24 additions & 0 deletions jsonrepair.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const fs = require('fs');
const { jsonrepair } = require('jsonrepair');

// This script processes command-line arguments
const filename = process.argv[2]; // Skip the first two elements
// Simple processing: join arguments into a stri

function processFile(filePath) {
try {
const data = fs.readFileSync(filePath, { encoding: 'utf8' });
const repairData = jsonrepair(data);
console.log(repairData);
fs.unlinkSync(filePath);
return repairData;
} catch (error) {
console.error('Error reading file:', error);
return '';
}
}


processFile(filename);
// Output the result

0 comments on commit 7511005

Please sign in to comment.