feat: catch-up de decisiones previas (Webpage→Url, anti-bot, UI 2-col, tests cross-platform)
Bloque de cambios revisados y validados con el usuario en sesiones previas que no habian aterrizado en commits propios. Lista por tema: * enrichers: web_search ahora usa lite.duckduckgo.com como endpoint primario (mas tolerante con bot detection desde IP residencial), con fallback al endpoint html. Detecta pagina captcha y emite error claro si ambos fallan. Anyade _DDGLiteParser para el formato lite + auto-pick de parser por contenido. * enrichers: tipo Webpage unificado en Url (campos de cuerpo cacheado viven en metadata del Url). Manifests actualizados (applies_to: [Url]). fetch_webpage ya no convierte Url->Webpage. * enrichers/manifest: campo `params` parseado a EnricherSpec.params (name, type, default_value, description). UI puede renderizar dialog de configuracion. * jobs: fix de path conversion para Python embebido nativo Windows (no convertir a /mnt/c/... cuando el subproceso es Windows-native; solo cuando es bash o python via WSL). * main.cpp: ventana ImGui (no modal) "Run enricher" con layout 2-col (label izq, input der). Inserta job con JSON tipado. Layout clustering apretado: hijos del mismo anchor en un solo anillo alrededor del padre, sin desperdigar por anillos crecientes. * views: inspector con layout 2-col via BeginTable (Identity, Schema fields, Extras). Description full-width debajo de su label. * tests: portable conftest (auto-detecta REGISTRY_ROOT, PYTHON_BIN, ENRICHERS_DIR para WSL y Windows portable). _runner.py trampoline inyecta stub via sys.path porque embedded Python ignora PYTHONPATH. Tests bash-only (vendor_script, freeze, dispatcher bash, resolver Linux-binary) skipean en Windows. Tests existentes adaptados a Webpage->Url. Resultado actual: 32 passed WSL, 21 passed + 11 skipped Windows.
This commit is contained in:
@@ -378,15 +378,20 @@ std::string read_entity_field(const char* db_path, const char* id,
|
||||
return out;
|
||||
}
|
||||
|
||||
// JSON entregado al subprocess. Todos los paths se normalizan a WSL en
|
||||
// Windows; en POSIX los respeta tal cual.
|
||||
// JSON entregado al subprocess. En Windows, los paths se normalizan a
|
||||
// forma WSL solo cuando el subprocess corre dentro de WSL (lang=bash, o
|
||||
// python con runtime registry_venv). Para subprocesses nativos Windows
|
||||
// (lang=go, o python embedded/FN_PYTHON/system) se mantienen los paths
|
||||
// Windows-nativos — pasarlos como /mnt/c/... haria que fallen al abrir.
|
||||
// En POSIX la conversion es no-op y siempre se respetan los paths.
|
||||
std::string build_stdin_json(const std::string& job_id,
|
||||
const std::string& enricher_id,
|
||||
const std::string& node_id,
|
||||
const std::string& params_json,
|
||||
const std::string& ops_db,
|
||||
const std::string& app_dir,
|
||||
const std::string& registry_root)
|
||||
const std::string& registry_root,
|
||||
const std::string& lang)
|
||||
{
|
||||
std::string node_type, node_name, node_metadata = "{}";
|
||||
if (!node_id.empty()) {
|
||||
@@ -420,10 +425,25 @@ std::string build_stdin_json(const std::string& job_id,
|
||||
std::string app_dir_abs = absify(app_dir);
|
||||
std::string root_abs = absify(registry_root);
|
||||
|
||||
std::string ops_db_wsl = to_wsl_path(ops_db_abs);
|
||||
std::string app_dir_wsl = to_wsl_path(app_dir_abs);
|
||||
std::string root_wsl = to_wsl_path(root_abs);
|
||||
std::string cache_dir = app_dir_wsl + "/cache";
|
||||
// Decidir si convertir paths a forma WSL. Solo se hace cuando el
|
||||
// subprocess vive dentro de WSL — si no, los paths /mnt/c/... no
|
||||
// existen para el proceso Windows-nativo.
|
||||
bool use_wsl_paths = false;
|
||||
#ifdef _WIN32
|
||||
if (lang == "bash") {
|
||||
use_wsl_paths = true;
|
||||
} else if (lang == "python") {
|
||||
use_wsl_paths = cached_python_runtime().needs_wsl;
|
||||
}
|
||||
// lang == "go": siempre nativo Windows.
|
||||
#else
|
||||
(void)lang;
|
||||
#endif
|
||||
|
||||
std::string ops_db_out = use_wsl_paths ? to_wsl_path(ops_db_abs) : ops_db_abs;
|
||||
std::string app_dir_out = use_wsl_paths ? to_wsl_path(app_dir_abs) : app_dir_abs;
|
||||
std::string root_out = use_wsl_paths ? to_wsl_path(root_abs) : root_abs;
|
||||
std::string cache_dir = app_dir_out + "/cache";
|
||||
|
||||
std::ostringstream o;
|
||||
o << '{'
|
||||
@@ -434,10 +454,10 @@ std::string build_stdin_json(const std::string& job_id,
|
||||
<< "\"node_name\":\"" << json_escape(node_name) << "\","
|
||||
<< "\"metadata\":" << (node_metadata.empty() ? "{}" : node_metadata) << ","
|
||||
<< "\"params\":" << (params_json.empty() ? "{}" : params_json) << ","
|
||||
<< "\"ops_db_path\":\"" << json_escape(ops_db_wsl) << "\","
|
||||
<< "\"app_dir\":\"" << json_escape(app_dir_wsl) << "\","
|
||||
<< "\"ops_db_path\":\"" << json_escape(ops_db_out) << "\","
|
||||
<< "\"app_dir\":\"" << json_escape(app_dir_out) << "\","
|
||||
<< "\"cache_dir\":\"" << json_escape(cache_dir) << "\","
|
||||
<< "\"registry_root\":\"" << json_escape(root_wsl) << "\""
|
||||
<< "\"registry_root\":\"" << json_escape(root_out) << "\""
|
||||
<< '}';
|
||||
return o.str();
|
||||
}
|
||||
@@ -1030,7 +1050,7 @@ void worker_loop() {
|
||||
}
|
||||
std::string stdin_payload = build_stdin_json(
|
||||
ctx.id, ctx.enricher_id, ctx.node_id, ctx.params_json,
|
||||
ops_db, g_state->app_dir, g_state->registry_root);
|
||||
ops_db, g_state->app_dir, g_state->registry_root, lang);
|
||||
|
||||
ProcResult res = run_subprocess(job_id, run_path, lang,
|
||||
stdin_payload, ctrl);
|
||||
|
||||
Reference in New Issue
Block a user