#include "fiko/mcp/zeka_araclari.hpp" namespace fiko::mcp { std::string luaMetinKacir(const std::string& m) { std::string s; s.reserve(m.size() + 8); s += '"'; for (unsigned char c : m) { switch (c) { case '"': s += "\\\""; break; case '\\': s += "\\\\"; break; case '\n': s += "\\n"; break; case '\r': s += "\\r"; break; case '\t': s += "\\t"; break; default: if (c < 0x20) { // ondalık kaçış; 3 haneli sabit (ardışık rakam güvenli) s += '\\'; s += (char)('0' + c / 100); s += (char)('0' + (c / 10) % 10); s += (char)('0' + c % 10); } else { s += (char)c; } } } s += '"'; return s; } namespace { // Ortak gövde: çağrı sonucu (s) çıktıya; hata (h) Lua error → makro kanalı // hataliDon döndürür (isError=true — istemciye Türkçe gerekçe aynen gider). std::string sonucLua(const std::string& cagri) { return "local s,h = " + cagri + " if s then fiko.log(s) else error(h or 'bilinmeyen hata', 0) end"; } Json kanalArgs(const Json& a, std::string kod) { Json alt = Json::nesne(); alt.ekle("kod", Json::metin(std::move(kod))); alt.ekle("pid", a["pid"]); alt.ekle("zaman_asimi_ms", a["zaman_asimi_ms"]); return alt; } } // namespace void zekaAraclariKaydet(McpSunucu& s, std::function makroKanal) { s.aracKaydet( {.ad = "zeka_pipeline", .aciklama = "Geometri Zeka Motoru graf sorgusu: GPE pipeline planini (JSON) calisan " "FikoCad'de kosar, sonuc JSON'unu dondurur. 'govde' verilirse o govde once " "cozulur (0 = secili govde); verilmezse mevcut graf uzerinde kosar. " "Feature'lar (cep, delik, fillet, pattern) ve iliskileri hazir graftan " "aninda gelir. Plan semasi: docs/gpe_mimari.md — ornek: " "{\"asamalar\":[{\"ad\":\"kaynak\",\"tip\":\"Cep\"},{\"ad\":\"say\"}]}", .sema = semaNesne( {{"pipeline", semaMetin("GPE plan JSON metni (docs/gpe_mimari.md semasi)")}, {"govde", semaSayi("Govde varlik kimligi; 0 = secili govde (opsiyonel)")}, {"pid", semaSayi("Hedef surec PID'i; verilmezse ilk calisan ornek")}, {"zaman_asimi_ms", semaSayi("Sonuc bekleme suresi (varsayilan 8000)")}}, {"pipeline"}), .lisansKimlik = "", .calistir = [makroKanal](const Json& a) { const std::string plan = a["pipeline"].metinAl(); if (plan.empty()) return AracSonuc::hataliDon("'pipeline' bos olamaz"); std::string cagri = "fiko.zeka.pipeline(" + luaMetinKacir(plan); if (a["govde"].varMi()) cagri += ", " + std::to_string(a["govde"].tamAl(0)); cagri += ")"; return makroKanal(kanalArgs(a, sonucLua(cagri))); }}); s.aracKaydet( {.ad = "zeka_ozet", .aciklama = "Govdenin Geometri Zeka Motoru ozetini dondurur: dugum tip sayilari " "(Yuz/Kenar/Cep/Delik/Fillet/Pattern...) JSON olarak. Govde cozulmemisse " "once cozulur. 'govde' verilmezse secili govde kullanilir. Derin sorgu " "icin zeka_pipeline aracina gecin.", .sema = semaNesne( {{"govde", semaSayi("Govde varlik kimligi; verilmezse secili govde")}, {"pid", semaSayi("Hedef surec PID'i; verilmezse ilk calisan ornek")}, {"zaman_asimi_ms", semaSayi("Sonuc bekleme suresi (varsayilan 8000)")}}, {}), .lisansKimlik = "", .calistir = [makroKanal](const Json& a) { std::string cagri = "fiko.zeka.ozet("; if (a["govde"].varMi()) cagri += std::to_string(a["govde"].tamAl(0)); cagri += ")"; return makroKanal(kanalArgs(a, sonucLua(cagri))); }}); } } // namespace fiko::mcp