Complete step458 transpilation RPC and MCP tools with tests
This commit is contained in:
@@ -3001,4 +3001,13 @@ target_link_libraries(step457_test PRIVATE
|
|||||||
tree_sitter_javascript tree_sitter_typescript
|
tree_sitter_javascript tree_sitter_typescript
|
||||||
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||||
|
|
||||||
|
add_executable(step458_test tests/step458_test.cpp)
|
||||||
|
target_include_directories(step458_test PRIVATE src)
|
||||||
|
target_link_libraries(step458_test PRIVATE
|
||||||
|
nlohmann_json::nlohmann_json
|
||||||
|
unofficial::tree-sitter::tree-sitter
|
||||||
|
tree_sitter_python tree_sitter_cpp tree_sitter_elisp
|
||||||
|
tree_sitter_javascript tree_sitter_typescript
|
||||||
|
tree_sitter_java tree_sitter_rust tree_sitter_go)
|
||||||
|
|
||||||
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)
|
# Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies)
|
||||||
|
|||||||
255
editor/src/TranspilationRPC.h
Normal file
255
editor/src/TranspilationRPC.h
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Step 458: Transpilation RPC + MCP tool definitions for semantic transpilation,
|
||||||
|
// reporting, equivalence checks, and confidence scoring.
|
||||||
|
|
||||||
|
#include "BehavioralEquivalence.h"
|
||||||
|
#include "IntentTranslator.h"
|
||||||
|
#include "TranslationReport.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
inline json confidenceToJson(const ConfidenceScore& s) {
|
||||||
|
return {
|
||||||
|
{"functionName", s.functionName},
|
||||||
|
{"sourceLanguage", s.sourceLanguage},
|
||||||
|
{"targetLanguage", s.targetLanguage},
|
||||||
|
{"score", s.score},
|
||||||
|
{"reviewRequired", s.reviewRequired},
|
||||||
|
{"annotation", s.annotation},
|
||||||
|
{"reviewReason", s.reviewReason}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline json fnReportToJson(const FunctionTranslationReport& f) {
|
||||||
|
return {
|
||||||
|
{"functionName", f.functionName},
|
||||||
|
{"sourceLanguage", f.sourceLanguage},
|
||||||
|
{"targetLanguage", f.targetLanguage},
|
||||||
|
{"sourceConstruct", f.sourceConstruct},
|
||||||
|
{"targetConstruct", f.targetConstruct},
|
||||||
|
{"confidence", f.confidence},
|
||||||
|
{"idiomatic", f.idiomatic},
|
||||||
|
{"reviewRequired", f.reviewRequired},
|
||||||
|
{"reviewReason", f.reviewReason},
|
||||||
|
{"safetyDelta", f.safetyDelta},
|
||||||
|
{"rationale", f.rationale},
|
||||||
|
{"annotations", {
|
||||||
|
{"added", f.annotations.added},
|
||||||
|
{"removed", f.annotations.removed},
|
||||||
|
{"changed", f.annotations.changed}
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline json equivalenceToJson(const BehavioralCheckResult& r) {
|
||||||
|
json assertions = json::array();
|
||||||
|
for (const auto& a : r.assertions) {
|
||||||
|
assertions.push_back({
|
||||||
|
{"functionName", a.functionName},
|
||||||
|
{"inputSpec", a.inputSpec},
|
||||||
|
{"expectedOutput", a.expectedOutput},
|
||||||
|
{"sameErrors", a.sameErrors},
|
||||||
|
{"confidenceScore", a.confidenceScore}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
{"functionName", r.functionName},
|
||||||
|
{"sourceLanguage", r.sourceLanguage},
|
||||||
|
{"targetLanguage", r.targetLanguage},
|
||||||
|
{"assertions", assertions},
|
||||||
|
{"allPassing", r.allPassing},
|
||||||
|
{"annotation", r.annotation}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class TranspilationRPCHandler {
|
||||||
|
public:
|
||||||
|
static json handleTranspile(const json& params) {
|
||||||
|
FunctionIntent fn{
|
||||||
|
params.value("functionName", "function"),
|
||||||
|
params.value("intent", ""),
|
||||||
|
params.value("source", "")
|
||||||
|
};
|
||||||
|
std::string sourceLanguage = params.value("sourceLanguage", "python");
|
||||||
|
std::string targetLanguage = params.value("targetLanguage", "rust");
|
||||||
|
auto result = IntentTranslator::translate({fn}, sourceLanguage, targetLanguage);
|
||||||
|
auto translation = result.getTranslation(fn.name);
|
||||||
|
|
||||||
|
return {
|
||||||
|
{"functionName", translation.functionName},
|
||||||
|
{"sourceLanguage", sourceLanguage},
|
||||||
|
{"targetLanguage", targetLanguage},
|
||||||
|
{"sourceCode", translation.sourceCode},
|
||||||
|
{"targetCode", translation.targetCode},
|
||||||
|
{"confidence", translation.confidence},
|
||||||
|
{"idiomatic", translation.isIdiomatic},
|
||||||
|
{"needsReview", translation.needsReview},
|
||||||
|
{"reviewReason", translation.reviewReason}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static json handleGetTranslationReport(const json& params) {
|
||||||
|
std::string sourceLanguage = params.value("sourceLanguage", "python");
|
||||||
|
std::string targetLanguage = params.value("targetLanguage", "rust");
|
||||||
|
json funcs = params.value("functions", json::array());
|
||||||
|
std::vector<FunctionIntent> fns;
|
||||||
|
for (const auto& f : funcs) {
|
||||||
|
fns.push_back({
|
||||||
|
f.value("name", "function"),
|
||||||
|
f.value("intent", ""),
|
||||||
|
f.value("source", "")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
auto translated = IntentTranslator::translate(fns, sourceLanguage, targetLanguage);
|
||||||
|
auto report = TranslationReportGenerator::generate(translated);
|
||||||
|
|
||||||
|
json functionReports = json::array();
|
||||||
|
for (const auto& fn : report.functions)
|
||||||
|
functionReports.push_back(fnReportToJson(fn));
|
||||||
|
|
||||||
|
return {
|
||||||
|
{"sourceLanguage", report.sourceLanguage},
|
||||||
|
{"targetLanguage", report.targetLanguage},
|
||||||
|
{"functions", functionReports},
|
||||||
|
{"summary", {
|
||||||
|
{"totalFunctions", report.summary.totalFunctions},
|
||||||
|
{"idiomaticCount", report.summary.idiomaticCount},
|
||||||
|
{"literalCount", report.summary.literalCount},
|
||||||
|
{"flaggedForReviewCount", report.summary.flaggedForReviewCount},
|
||||||
|
{"idiomaticPercent", report.summary.idiomaticPercent()},
|
||||||
|
{"literalPercent", report.summary.literalPercent()},
|
||||||
|
{"reviewPercent", report.summary.reviewPercent()}
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static json handleVerifyEquivalence(const json& params) {
|
||||||
|
std::string functionName = params.value("functionName", "function");
|
||||||
|
std::string sourceCode = params.value("sourceCode", "");
|
||||||
|
std::string targetCode = params.value("targetCode", "");
|
||||||
|
std::string sourceLanguage = params.value("sourceLanguage", "python");
|
||||||
|
std::string targetLanguage = params.value("targetLanguage", "rust");
|
||||||
|
|
||||||
|
std::vector<std::string> sampleInputs;
|
||||||
|
if (params.contains("sampleInputs")) {
|
||||||
|
for (const auto& s : params["sampleInputs"])
|
||||||
|
sampleInputs.push_back(s.get<std::string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = BehavioralChecker::check(
|
||||||
|
functionName, sourceCode, targetCode, sourceLanguage, targetLanguage, sampleInputs);
|
||||||
|
return equivalenceToJson(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static json handleGetConfidence(const json& params) {
|
||||||
|
std::string functionName = params.value("functionName", "function");
|
||||||
|
std::string sourceCode = params.value("sourceCode", "");
|
||||||
|
std::string targetCode = params.value("targetCode", "");
|
||||||
|
std::string sourceLanguage = params.value("sourceLanguage", "python");
|
||||||
|
std::string targetLanguage = params.value("targetLanguage", "rust");
|
||||||
|
bool hasIntent = params.value("hasIntent", false);
|
||||||
|
|
||||||
|
auto score = TranspilationScorer::score(
|
||||||
|
functionName, sourceCode, targetCode, sourceLanguage, targetLanguage, hasIntent);
|
||||||
|
return confidenceToJson(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool canHandle(const std::string& method) {
|
||||||
|
return method == "transpile" ||
|
||||||
|
method == "getTranslationReport" ||
|
||||||
|
method == "verifyEquivalence" ||
|
||||||
|
method == "getConfidence";
|
||||||
|
}
|
||||||
|
|
||||||
|
static json dispatch(const std::string& method, const json& params, const json& id) {
|
||||||
|
json result;
|
||||||
|
if (method == "transpile")
|
||||||
|
result = handleTranspile(params);
|
||||||
|
else if (method == "getTranslationReport")
|
||||||
|
result = handleGetTranslationReport(params);
|
||||||
|
else if (method == "verifyEquivalence")
|
||||||
|
result = handleVerifyEquivalence(params);
|
||||||
|
else if (method == "getConfidence")
|
||||||
|
result = handleGetConfidence(params);
|
||||||
|
else
|
||||||
|
return {{"jsonrpc", "2.0"}, {"id", id},
|
||||||
|
{"error", {{"code", -32601}, {"message", "Unknown method"}}}};
|
||||||
|
return {{"jsonrpc", "2.0"}, {"id", id}, {"result", result}};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MCPToolDef {
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
json inputSchema;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<MCPToolDef> toolDefinitions() {
|
||||||
|
json transpileSchema = {
|
||||||
|
{"type", "object"},
|
||||||
|
{"properties", {
|
||||||
|
{"functionName", {{"type", "string"}}},
|
||||||
|
{"intent", {{"type", "string"}}},
|
||||||
|
{"source", {{"type", "string"}}},
|
||||||
|
{"sourceLanguage", {{"type", "string"}}},
|
||||||
|
{"targetLanguage", {{"type", "string"}}}
|
||||||
|
}},
|
||||||
|
{"required", json::array({"functionName", "source"})}
|
||||||
|
};
|
||||||
|
|
||||||
|
json reportSchema = {
|
||||||
|
{"type", "object"},
|
||||||
|
{"properties", {
|
||||||
|
{"functions", {{"type", "array"}}},
|
||||||
|
{"sourceLanguage", {{"type", "string"}}},
|
||||||
|
{"targetLanguage", {{"type", "string"}}}
|
||||||
|
}},
|
||||||
|
{"required", json::array({"functions"})}
|
||||||
|
};
|
||||||
|
|
||||||
|
json eqSchema = {
|
||||||
|
{"type", "object"},
|
||||||
|
{"properties", {
|
||||||
|
{"functionName", {{"type", "string"}}},
|
||||||
|
{"sourceCode", {{"type", "string"}}},
|
||||||
|
{"targetCode", {{"type", "string"}}},
|
||||||
|
{"sourceLanguage", {{"type", "string"}}},
|
||||||
|
{"targetLanguage", {{"type", "string"}}},
|
||||||
|
{"sampleInputs", {{"type", "array"}}}
|
||||||
|
}},
|
||||||
|
{"required", json::array({"functionName", "sourceCode", "targetCode"})}
|
||||||
|
};
|
||||||
|
|
||||||
|
json confidenceSchema = {
|
||||||
|
{"type", "object"},
|
||||||
|
{"properties", {
|
||||||
|
{"functionName", {{"type", "string"}}},
|
||||||
|
{"sourceCode", {{"type", "string"}}},
|
||||||
|
{"targetCode", {{"type", "string"}}},
|
||||||
|
{"sourceLanguage", {{"type", "string"}}},
|
||||||
|
{"targetLanguage", {{"type", "string"}}},
|
||||||
|
{"hasIntent", {{"type", "boolean"}}}
|
||||||
|
}},
|
||||||
|
{"required", json::array({"functionName", "sourceCode", "targetCode"})}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
{"whetstone_transpile",
|
||||||
|
"Transpile a function using semantic intent-aware translation.",
|
||||||
|
transpileSchema},
|
||||||
|
{"whetstone_get_translation_report",
|
||||||
|
"Generate per-function and project-level translation report.",
|
||||||
|
reportSchema},
|
||||||
|
{"whetstone_verify_equivalence",
|
||||||
|
"Generate behavioral equivalence assertions for source vs target.",
|
||||||
|
eqSchema},
|
||||||
|
{"whetstone_get_confidence",
|
||||||
|
"Get confidence score and review requirement for a translation.",
|
||||||
|
confidenceSchema}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
193
editor/tests/step458_test.cpp
Normal file
193
editor/tests/step458_test.cpp
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
// Step 458: Transpilation RPC + MCP Tests (12 tests)
|
||||||
|
|
||||||
|
#include "TranspilationRPC.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
static int passed = 0, failed = 0;
|
||||||
|
#define TEST(name) { std::cout << " " << #name << "... "; }
|
||||||
|
#define PASS() { std::cout << "PASS\n"; ++passed; }
|
||||||
|
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
|
||||||
|
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
|
||||||
|
|
||||||
|
void test_can_handle_all_methods() {
|
||||||
|
TEST(can_handle_all_methods);
|
||||||
|
CHECK(TranspilationRPCHandler::canHandle("transpile"), "missing transpile");
|
||||||
|
CHECK(TranspilationRPCHandler::canHandle("getTranslationReport"), "missing getTranslationReport");
|
||||||
|
CHECK(TranspilationRPCHandler::canHandle("verifyEquivalence"), "missing verifyEquivalence");
|
||||||
|
CHECK(TranspilationRPCHandler::canHandle("getConfidence"), "missing getConfidence");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_handle_transpile_returns_target_code() {
|
||||||
|
TEST(handle_transpile_returns_target_code);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "sort_items"},
|
||||||
|
{"intent", "sort list ascending"},
|
||||||
|
{"source", "items.sort()"},
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "rust"}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleTranspile(params);
|
||||||
|
CHECK(r["functionName"] == "sort_items", "wrong function name");
|
||||||
|
CHECK(r["targetCode"].get<std::string>().find("sort") != std::string::npos,
|
||||||
|
"expected sort mapping");
|
||||||
|
CHECK(r["idiomatic"].get<bool>(), "expected idiomatic translation");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_handle_translation_report_returns_summary() {
|
||||||
|
TEST(handle_translation_report_returns_summary);
|
||||||
|
json params = {
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "rust"},
|
||||||
|
{"functions", json::array({
|
||||||
|
{{"name", "sort_items"}, {"intent", "sort list ascending"}, {"source", "items.sort()"}},
|
||||||
|
{{"name", "mystery"}, {"intent", ""}, {"source", "x = a + b"}}
|
||||||
|
})}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleGetTranslationReport(params);
|
||||||
|
CHECK(r.contains("summary"), "missing summary");
|
||||||
|
CHECK(r["summary"]["totalFunctions"] == 2, "wrong function count");
|
||||||
|
CHECK(r["functions"].size() == 2, "wrong function report count");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_handle_verify_equivalence_returns_assertions() {
|
||||||
|
TEST(handle_verify_equivalence_returns_assertions);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "sort_items"},
|
||||||
|
{"sourceCode", "sort values"},
|
||||||
|
{"targetCode", "items.sort()"},
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "rust"}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleVerifyEquivalence(params);
|
||||||
|
CHECK(r["functionName"] == "sort_items", "wrong function");
|
||||||
|
CHECK(r["assertions"].size() >= 1, "expected assertions");
|
||||||
|
CHECK(r.contains("annotation"), "missing annotation");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_handle_get_confidence_returns_score() {
|
||||||
|
TEST(handle_get_confidence_returns_score);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "sort_items"},
|
||||||
|
{"sourceCode", "sort values"},
|
||||||
|
{"targetCode", "items.sort()"},
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "rust"},
|
||||||
|
{"hasIntent", true}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleGetConfidence(params);
|
||||||
|
CHECK(r["score"].get<float>() >= 0.90f, "expected high confidence");
|
||||||
|
CHECK(!r["reviewRequired"].get<bool>(), "high confidence should not need review");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_dispatch_wraps_result_in_jsonrpc_shape() {
|
||||||
|
TEST(dispatch_wraps_result_in_jsonrpc_shape);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "sort_items"},
|
||||||
|
{"intent", "sort list ascending"},
|
||||||
|
{"source", "items.sort()"}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::dispatch("transpile", params, 7);
|
||||||
|
CHECK(r["jsonrpc"] == "2.0", "wrong jsonrpc version");
|
||||||
|
CHECK(r["id"] == 7, "wrong id");
|
||||||
|
CHECK(r.contains("result"), "missing result");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_dispatch_unknown_method_returns_error() {
|
||||||
|
TEST(dispatch_unknown_method_returns_error);
|
||||||
|
auto r = TranspilationRPCHandler::dispatch("unknownMethod", json::object(), 8);
|
||||||
|
CHECK(r.contains("error"), "missing error");
|
||||||
|
CHECK(r["error"]["code"] == -32601, "wrong error code");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_tool_definitions_contains_four_tools() {
|
||||||
|
TEST(tool_definitions_contains_four_tools);
|
||||||
|
auto defs = TranspilationRPCHandler::toolDefinitions();
|
||||||
|
CHECK(defs.size() == 4, "expected 4 tool defs");
|
||||||
|
CHECK(defs[0].name == "whetstone_transpile", "first tool mismatch");
|
||||||
|
CHECK(defs[1].name == "whetstone_get_translation_report", "second tool mismatch");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_tool_schemas_have_required_fields() {
|
||||||
|
TEST(tool_schemas_have_required_fields);
|
||||||
|
auto defs = TranspilationRPCHandler::toolDefinitions();
|
||||||
|
CHECK(defs[0].inputSchema.contains("required"), "missing required on transpile schema");
|
||||||
|
CHECK(defs[2].inputSchema.contains("required"), "missing required on equivalence schema");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_transpile_rpc_without_intent_marks_review() {
|
||||||
|
TEST(transpile_rpc_without_intent_marks_review);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "mystery"},
|
||||||
|
{"intent", ""},
|
||||||
|
{"source", "x = a + b"},
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "rust"}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleTranspile(params);
|
||||||
|
CHECK(r["needsReview"].get<bool>(), "missing review flag for no-intent case");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_confidence_rpc_low_score_requests_review() {
|
||||||
|
TEST(confidence_rpc_low_score_requests_review);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "unknown"},
|
||||||
|
{"sourceCode", "custom op"},
|
||||||
|
{"targetCode", "TODO: translate"},
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "rust"},
|
||||||
|
{"hasIntent", false}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleGetConfidence(params);
|
||||||
|
CHECK(r["score"].get<float>() <= 0.30f, "expected low confidence");
|
||||||
|
CHECK(r["reviewRequired"].get<bool>(), "expected review requirement");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_equivalence_rpc_uses_custom_inputs() {
|
||||||
|
TEST(equivalence_rpc_uses_custom_inputs);
|
||||||
|
json params = {
|
||||||
|
{"functionName", "custom"},
|
||||||
|
{"sourceCode", "custom op"},
|
||||||
|
{"targetCode", "custom_op(data)"},
|
||||||
|
{"sourceLanguage", "python"},
|
||||||
|
{"targetLanguage", "java"},
|
||||||
|
{"sampleInputs", json::array({"A", "B"})}
|
||||||
|
};
|
||||||
|
auto r = TranspilationRPCHandler::handleVerifyEquivalence(params);
|
||||||
|
CHECK(r["assertions"].size() == 2, "expected two custom assertions");
|
||||||
|
PASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Step 458: Transpilation RPC + MCP Tests\n";
|
||||||
|
|
||||||
|
test_can_handle_all_methods(); // 1
|
||||||
|
test_handle_transpile_returns_target_code(); // 2
|
||||||
|
test_handle_translation_report_returns_summary(); // 3
|
||||||
|
test_handle_verify_equivalence_returns_assertions(); // 4
|
||||||
|
test_handle_get_confidence_returns_score(); // 5
|
||||||
|
test_dispatch_wraps_result_in_jsonrpc_shape(); // 6
|
||||||
|
test_dispatch_unknown_method_returns_error(); // 7
|
||||||
|
test_tool_definitions_contains_four_tools(); // 8
|
||||||
|
test_tool_schemas_have_required_fields(); // 9
|
||||||
|
test_transpile_rpc_without_intent_marks_review(); // 10
|
||||||
|
test_confidence_rpc_low_score_requests_review(); // 11
|
||||||
|
test_equivalence_rpc_uses_custom_inputs(); // 12
|
||||||
|
|
||||||
|
std::cout << "\nResults: " << passed << "/" << (passed + failed)
|
||||||
|
<< " passed\n";
|
||||||
|
return failed == 0 ? 0 : 1;
|
||||||
|
}
|
||||||
37
progress.md
37
progress.md
@@ -5941,3 +5941,40 @@ and review-flag rollups.
|
|||||||
**Architecture gate check:**
|
**Architecture gate check:**
|
||||||
- `editor/src/TranslationReport.h` within header-size limit (`174` <= `600`)
|
- `editor/src/TranslationReport.h` within header-size limit (`174` <= `600`)
|
||||||
- `editor/tests/step457_test.cpp` within test-file size guidance (`168` lines)
|
- `editor/tests/step457_test.cpp` within test-file size guidance (`168` lines)
|
||||||
|
|
||||||
|
### Step 458: Transpilation RPC + MCP
|
||||||
|
**Status:** PASS (12/12 tests)
|
||||||
|
|
||||||
|
Exposes semantic transpilation/reporting/equivalence/confidence as JSON-RPC
|
||||||
|
handlers and MCP tool definitions.
|
||||||
|
|
||||||
|
**Files added:**
|
||||||
|
- `editor/src/TranspilationRPC.h` — RPC + MCP handler:
|
||||||
|
- JSON handlers:
|
||||||
|
- `transpile`
|
||||||
|
- `getTranslationReport`
|
||||||
|
- `verifyEquivalence`
|
||||||
|
- `getConfidence`
|
||||||
|
- `canHandle` + `dispatch` integration shape (JSON-RPC 2.0 envelope)
|
||||||
|
- MCP tool definitions:
|
||||||
|
- `whetstone_transpile`
|
||||||
|
- `whetstone_get_translation_report`
|
||||||
|
- `whetstone_verify_equivalence`
|
||||||
|
- `whetstone_get_confidence`
|
||||||
|
- JSON serialization helpers for confidence/report/equivalence payloads
|
||||||
|
- `editor/tests/step458_test.cpp` — 12 tests covering:
|
||||||
|
- handler method coverage and dispatch behavior
|
||||||
|
- result schema/content validation for each RPC method
|
||||||
|
- unknown-method error envelope
|
||||||
|
- MCP tool definition count/names/schema-required fields
|
||||||
|
- low-confidence review and no-intent review behavior
|
||||||
|
- `editor/CMakeLists.txt` — `step458_test` target
|
||||||
|
|
||||||
|
**Verification run:**
|
||||||
|
- `cmake --build editor/build-native --target step458_test` — PASS
|
||||||
|
- `./editor/build-native/step458_test` — PASS (12/12)
|
||||||
|
- `./editor/build-native/step457_test` — PASS (12/12) regression coverage
|
||||||
|
|
||||||
|
**Architecture gate check:**
|
||||||
|
- `editor/src/TranspilationRPC.h` within header-size limit (`255` <= `600`)
|
||||||
|
- `editor/tests/step458_test.cpp` within test-file size guidance (`193` lines)
|
||||||
|
|||||||
Reference in New Issue
Block a user