@arcadialdev/arcality 2.4.35 → 2.4.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -939,11 +939,11 @@ ${relevantFailures.map((m) => `- ${m.prompt}`).join("\n")}
|
|
|
939
939
|
const role = htmlEl.getAttribute("role") || "";
|
|
940
940
|
const text = (htmlEl.innerText || htmlEl.getAttribute("aria-label") || htmlEl.getAttribute("title") || "").trim().replace(/\s+/g, " ");
|
|
941
941
|
const textLower = text.toLowerCase();
|
|
942
|
-
const isCriticalFailure = (textLower.includes("error") || textLower.includes("fall\xF3") || textLower.includes("no se puede") || textLower.includes("ya existe") || textLower.includes("
|
|
942
|
+
const isCriticalFailure = (textLower.includes("error") || textLower.includes("fall\xF3") || textLower.includes("no se puede") || textLower.includes("ya existe") || textLower.includes("inv\xE1lido") || textLower.includes("incorrecto") || textLower.includes("ligado") || textLower.includes("depende") || textLower.includes("duplicado") || textLower.includes("repetido") || /* Validaciones ZOD / Wizard de campos de formulario */
|
|
943
943
|
textLower.includes("debe ser mayor") || textLower.includes("debe ser menor") || textLower.includes("debe ser igual") || textLower.includes("debe ser mayor o igual") || textLower.includes("debe ser menor o igual") || /* ZOD date messages (Spanish) */
|
|
944
944
|
textLower.includes("debe ser posterior") || textLower.includes("debe ser anterior") || textLower.includes("debe ser una fecha") || textLower.includes("fecha debe ser") || textLower.includes("posterior o igual a la fecha") || textLower.includes("anterior o igual a la fecha") || textLower.includes("posterior a la fecha") || textLower.includes("anterior a la fecha") || textLower.includes("fecha") && (textLower.includes("actual") || textLower.includes("pasada") || textLower.includes("futura") || textLower.includes("requerida") || textLower.includes("inv\xE1lida") || textLower.includes("incorrecta") || textLower.includes("posterior") || textLower.includes("anterior")) || /* ZOD number/range messages */
|
|
945
|
-
textLower.includes("debe ser un n\xFAmero") || textLower.includes("debe ser positivo") || textLower.includes("debe ser negativo") || textLower.includes("m\xEDnimo") && textLower.includes("caracteres") || textLower.includes("m\xE1ximo") && textLower.includes("caracteres") ||
|
|
946
|
-
textLower.includes("campo requerido") || textLower.includes("campo obligatorio") || textLower.includes("requerido") || textLower.includes("obligatorio") || textLower.includes("no puede estar vac\xEDo") || textLower.includes("no puede ser") || textLower.includes("no es v\xE1lido") || textLower.includes("no es correcto") || textLower.includes("
|
|
945
|
+
textLower.includes("debe ser un n\xFAmero") || textLower.includes("debe ser positivo") || textLower.includes("debe ser negativo") || textLower.includes("m\xEDnimo") && textLower.includes("caracteres") || textLower.includes("m\xE1ximo") && textLower.includes("caracteres") || /* Generic ZOD/form required — must be specific, NOT broad instructional text */
|
|
946
|
+
textLower.includes("campo requerido") || textLower.includes("campo obligatorio") || textLower === "requerido" || textLower === "obligatorio" || textLower.includes("este campo es requerido") || textLower.includes("este campo es obligatorio") || textLower.includes("no puede estar vac\xEDo") || textLower.includes("no puede ser") || textLower.includes("no es v\xE1lido") || textLower.includes("no es correcto") || textLower.includes("formato incorrecto") || textLower.includes("formato inv\xE1lido") || textLower.includes("valor no permitido")) && text.length < 200 && !textLower.includes("recuerda") && !textLower.includes("antes de guardar");
|
|
947
947
|
const isCriticalSuccess = (textLower.includes("exitosamente") || textLower.includes("guardado") || textLower.includes("creado") || textLower.includes("success") || textLower.includes("correctamente") && text.length < 100) && text.length < 200;
|
|
948
948
|
const isCriticalFeedback = isCriticalFailure || isCriticalSuccess;
|
|
949
949
|
if (!isCriticalFeedback && (tag === "span" || tag === "p" || tag === "label" || tag === "i" || tag === "svg" || tag === "img" || tag === "div")) {
|
|
@@ -956,6 +956,48 @@ ${relevantFailures.map((m) => `- ${m.prompt}`).join("\n")}
|
|
|
956
956
|
const idx = startIdx + localCount++;
|
|
957
957
|
htmlEl.setAttribute("agent-idx", idx.toString());
|
|
958
958
|
let name = text || htmlEl.getAttribute("aria-label") || htmlEl.getAttribute("title") || htmlEl.getAttribute("placeholder");
|
|
959
|
+
if (!name && (tag === "input" || tag === "select" || htmlEl.getAttribute("role") === "combobox")) {
|
|
960
|
+
const labelledBy = htmlEl.getAttribute("aria-labelledby");
|
|
961
|
+
if (labelledBy) {
|
|
962
|
+
const labelEl = document.getElementById(labelledBy);
|
|
963
|
+
if (labelEl)
|
|
964
|
+
name = labelEl.innerText.trim();
|
|
965
|
+
}
|
|
966
|
+
if (!name && htmlEl.id) {
|
|
967
|
+
const forLabel = document.querySelector(`label[for="${htmlEl.id}"]`);
|
|
968
|
+
if (forLabel)
|
|
969
|
+
name = forLabel.innerText.trim();
|
|
970
|
+
}
|
|
971
|
+
if (!name) {
|
|
972
|
+
const parentLabel = htmlEl.closest("label");
|
|
973
|
+
if (parentLabel)
|
|
974
|
+
name = parentLabel.innerText.replace(htmlEl.textContent || "", "").trim();
|
|
975
|
+
}
|
|
976
|
+
if (!name) {
|
|
977
|
+
let prev = htmlEl.previousElementSibling;
|
|
978
|
+
let tries = 0;
|
|
979
|
+
while (prev && tries < 3) {
|
|
980
|
+
const prevText = (prev.innerText || "").trim();
|
|
981
|
+
if (prevText && prevText.length > 1 && prevText.length < 60) {
|
|
982
|
+
name = prevText;
|
|
983
|
+
break;
|
|
984
|
+
}
|
|
985
|
+
prev = prev.previousElementSibling;
|
|
986
|
+
tries++;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (!name) {
|
|
990
|
+
const container = htmlEl.closest("div, fieldset, section");
|
|
991
|
+
if (container) {
|
|
992
|
+
const labelInContainer = container.querySelector('label, [class*="label"], [class*="placeholder"]');
|
|
993
|
+
if (labelInContainer) {
|
|
994
|
+
const labelText = (labelInContainer.innerText || "").trim();
|
|
995
|
+
if (labelText && labelText.length < 60)
|
|
996
|
+
name = labelText;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
959
1001
|
if (!name) {
|
|
960
1002
|
const iconMatch = htmlEl.outerHTML.match(/fa-([a-z0-9-]+)|md-([a-z0-9-]+)|bi-([a-z0-9-]+)/i);
|
|
961
1003
|
if (iconMatch) {
|
|
@@ -1205,10 +1247,18 @@ ${relevantFailures.map((m) => `- ${m.prompt}`).join("\n")}
|
|
|
1205
1247
|
return c.selector === memStep.action_data?.selector || cleanMemName !== "" && (cleanMemName === cleanCurrName || cleanCurrName.includes(cleanMemName));
|
|
1206
1248
|
});
|
|
1207
1249
|
if (!foundComponent && memStep.action_data?.action !== "wait") {
|
|
1208
|
-
console.log(`>>ARCALITY_STATUS>> \u23F3 Componente target no visible ("${memStep.componentName}"). Forzando espera de transici\xF3n DOM...`);
|
|
1209
1250
|
console.log(`>>ARCALITY_STATUS>> \u{1F50D} Descartado (Componente visual no encontrado: ${memStep.componentName})`);
|
|
1210
1251
|
return null;
|
|
1211
1252
|
}
|
|
1253
|
+
if (foundComponent && memStep.action_data?.action === "fill") {
|
|
1254
|
+
const compType = (foundComponent.type || "").toLowerCase();
|
|
1255
|
+
const compName = (foundComponent.name || "").toLowerCase();
|
|
1256
|
+
const looksLikeDropdown = compType.includes("select") || compType.includes("combobox") || compName.includes("tipo") || compName.includes("type") || compName.includes("categor\xEDa") || compName.includes("estado") || compName.includes("frecuencia") || compName.includes("alcance");
|
|
1257
|
+
if (looksLikeDropdown) {
|
|
1258
|
+
console.log(`>>ARCALITY_STATUS>> \u{1F50D} Descartado (fill en dropdown detectado: ${foundComponent.name}). Delegando a IA.`);
|
|
1259
|
+
return null;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1212
1262
|
const memCompName = memStep.componentName || "";
|
|
1213
1263
|
if (memCompName.length > 80) {
|
|
1214
1264
|
console.log(`>>ARCALITY_STATUS>> \u{1F50D} Descartado (Mensaje enorme o nombre inconsistente: ${memCompName.substring(0, 20)}...)`);
|
|
@@ -1463,6 +1513,10 @@ These are NOT optional. You MUST use these tools in these situations:
|
|
|
1463
1513
|
# CRITICAL RULES
|
|
1464
1514
|
1. **NEVER BLIND-RETRY**: If an action fails, you MUST investigate with \`inspect_element_details\` before retrying. Repeating the exact same failed action is FORBIDDEN.
|
|
1465
1515
|
2. **NO REPEAT ACTIONS**: Check HISTORY. If you already filled a field or clicked a button, do NOT do it again unless the UI clearly reset OR the button belongs to a different step/modal/section mentioned in the mission (e.g., Save in modal vs Save in main form).
|
|
1516
|
+
3. **GROUP ACTIONS**: You MUST group non-conflicting actions in a single turn to save time and tokens. You can \`fill\` multiple text inputs in the SAME turn.
|
|
1517
|
+
- NEVER use \`click\` on a text field before using \`fill\`. The \`fill\` action automatically focuses the field.
|
|
1518
|
+
- Example: \`fill\` Nombre, \`fill\` Fecha, \`fill\` Descripci\xF3n all in one single turn.
|
|
1519
|
+
- BUT keep dropdown interactions isolated: Turn A = \`click\` dropdown. Turn B = \`click\` option.
|
|
1466
1520
|
|
|
1467
1521
|
3. **CURRENT STATE > MEMORY**: What you see in CURRENT COMPONENTS is the truth. SUCCESS MEMORY is a guide, not gospel.
|
|
1468
1522
|
4. **PAGE TRANSITIONS**: If URL contains '/edit' or you see a 'Save' button, you ARE in the edit view. Don't go back.
|
|
@@ -1493,9 +1547,7 @@ These are NOT optional. You MUST use these tools in these situations:
|
|
|
1493
1547
|
# WIZARD & MULTI-STEP FORMS (CRITICAL)
|
|
1494
1548
|
When a form is divided into numbered steps (e.g., Step 1 \u2192 Step 2 \u2192 Step 3):
|
|
1495
1549
|
|
|
1496
|
-
1. **VALIDATION ERROR ON
|
|
1497
|
-
- Look for a "Back" / "Anterior" / "Periodo" / step-number button and click it to return.
|
|
1498
|
-
- NEVER retry the Save button without first fixing the invalid data in the previous step.
|
|
1550
|
+
1. **VALIDATION ERROR ON ADVANCE**: If you click "Next/Siguiente" and the UI DOES NOT advance to the next step, AND you see a \u{1F6D1} [ERROR_CR\xCDTICO], you must fix the data on the CURRENT step. DO NOT GO BACK to previous steps simply because you see an error, unless the error explicitly states that a previous step's data is invalid.
|
|
1499
1551
|
|
|
1500
1552
|
2. **DATE VALIDATION ERRORS \u2014 MANDATORY PROTOCOL (ZOD-AWARE)**:
|
|
1501
1553
|
- ZOD generates Spanish validation messages such as:
|
|
@@ -1506,8 +1558,8 @@ When a form is divided into numbered steps (e.g., Step 1 \u2192 Step 2 \u2192 St
|
|
|
1506
1558
|
- ANY \u{1F6D1} [ERROR_CR\xCDTICO] containing FECHA + (POSTERIOR/ANTERIOR/ACTUAL/PASADA/FUTURA) is a **ZOD DATE VALIDATION ERROR**.
|
|
1507
1559
|
- **RECOVERY PROTOCOL** (follow in order, NEVER skip):
|
|
1508
1560
|
1. STOP \u2014 do NOT click Save/Siguiente again with the same data.
|
|
1509
|
-
2. Identify which wizard step contains the failing date field (check HISTORY
|
|
1510
|
-
3.
|
|
1561
|
+
2. Identify which wizard step contains the failing date field (check HISTORY).
|
|
1562
|
+
3. If you are NOT on that step, click the Back/Anterior button to return to it.
|
|
1511
1563
|
4. Locate the date input using \`validate_element_state\` with 'has_value' to confirm its current (bad) value.
|
|
1512
1564
|
5. Clear and re-fill the date using \`interact_native_control\` with control_type \`'date'\` and a value \u2265 TODAY in YYYY-MM-DD format.
|
|
1513
1565
|
6. TODAY: \`${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}\` \u2014 use this exact expression to compute the date dynamically.
|
|
@@ -1515,7 +1567,9 @@ When a form is divided into numbered steps (e.g., Step 1 \u2192 Step 2 \u2192 St
|
|
|
1515
1567
|
|
|
1516
1568
|
3. **NEVER LOOP ON THE SAME STEP**: If you've been on the same wizard step for 3+ turns without advancing, go back one step and verify the data is correct before trying to advance again.
|
|
1517
1569
|
|
|
1518
|
-
4. **STEP VERIFICATION**: Before clicking Next/Save on any step, VERIFY that date fields have future-or-today dates. Use \`validate_element_state\` with 'has_value' to confirm
|
|
1570
|
+
4. **STEP VERIFICATION**: Before clicking Next/Save on any step, VERIFY that date fields have future-or-today dates. Use \`validate_element_state\` with 'has_value' to confirm.
|
|
1571
|
+
|
|
1572
|
+
5. **FINAL PREVIEW STEP**: If you reach a final step like "Previsualizaci\xF3n", "Resumen", or see a "Terminar" / "Finalizar" button, your objective is ALMOST COMPLETE. Do NOT go back to previous steps just because you see read-only data. Click the final submit button ("Terminar", "Guardar", "Finalizar") to complete the mission.`
|
|
1519
1573
|
}
|
|
1520
1574
|
];
|
|
1521
1575
|
if (this.testInfo) {
|
|
@@ -1647,7 +1701,12 @@ ${history.slice(-25).join("\n") || "None"}`
|
|
|
1647
1701
|
const textResponse = message.content.find((c) => c.type === "text")?.text || "";
|
|
1648
1702
|
if (toolCalls.length === 0) {
|
|
1649
1703
|
console.log(`(${((Date.now() - startTime) / 1e3).toFixed(1)}s)`);
|
|
1650
|
-
|
|
1704
|
+
console.log(`>>ARCALITY_STATUS>> \u26A0\uFE0F Agente devolvi\xF3 texto sin acci\xF3n. Reinyectando instrucci\xF3n mandatoria...`);
|
|
1705
|
+
anthropicMessages.push({
|
|
1706
|
+
role: "user",
|
|
1707
|
+
content: [{ type: "text", text: `MANDATORY: You MUST call one of the available tools right now. You are NOT allowed to return plain text only. If you are unsure, call 'perform_ui_actions' with the most logical next action based on the mission and history. If you are truly stuck, call 'report_inability_to_proceed'. DO NOT return text without a tool call.` }]
|
|
1708
|
+
});
|
|
1709
|
+
continue;
|
|
1651
1710
|
}
|
|
1652
1711
|
const toolResults = [];
|
|
1653
1712
|
let uiActionCall = null;
|
|
@@ -2863,14 +2922,17 @@ function captureValidationRule(errorMessage, context) {
|
|
|
2863
2922
|
}
|
|
2864
2923
|
}
|
|
2865
2924
|
const lastAction = history[history.length - 1];
|
|
2866
|
-
|
|
2925
|
+
const isGenericName = !desc || desc === "[input]" || desc === "[button]" || desc === "[select]" || desc === "[div]" || desc.trim().length < 3;
|
|
2926
|
+
if (!isGenericName && lastAction && lastAction.includes(`click en "${desc}"`)) {
|
|
2867
2927
|
const isDotsTrigger = desc.includes("dots") || desc.includes("vert") || desc.includes("menu") || desc.includes("opciones");
|
|
2868
2928
|
const sameActionCount = history.filter((h) => h.includes(`click en "${desc}"`)).length;
|
|
2869
|
-
const toleranceLimit = allowRepeatedNames ?
|
|
2870
|
-
if (isDotsTrigger && sameActionCount <
|
|
2929
|
+
const toleranceLimit = allowRepeatedNames ? 4 : 2;
|
|
2930
|
+
if (isDotsTrigger && sameActionCount < 3) {
|
|
2871
2931
|
console.log(` \u26A0\uFE0F Re-intentando click en men\xFA "${desc}"...`);
|
|
2872
2932
|
} else if (allowRepeatedNames && sameActionCount < toleranceLimit) {
|
|
2873
2933
|
console.log(` \u26A0\uFE0F Click repetido permitido por contexto de misi\xF3n en "${desc}"...`);
|
|
2934
|
+
} else if (sameActionCount < toleranceLimit) {
|
|
2935
|
+
console.log(` \u26A0\uFE0F Re-intento ${sameActionCount} en "${desc}"...`);
|
|
2874
2936
|
} else {
|
|
2875
2937
|
const bodyText = await page.innerText("body").catch(() => "");
|
|
2876
2938
|
if (bodyText.match(/ligado|depende|no se puede/i)) {
|
|
@@ -2881,9 +2943,9 @@ function captureValidationRule(errorMessage, context) {
|
|
|
2881
2943
|
break;
|
|
2882
2944
|
}
|
|
2883
2945
|
console.log(`
|
|
2884
|
-
\u{1F6D1} [AUTO-STOP] Bloqueando click
|
|
2885
|
-
history.push(`Turno ${stepCount}:
|
|
2886
|
-
await page.waitForTimeout(
|
|
2946
|
+
\u{1F6D1} [AUTO-STOP] Bloqueando click repetido en "${desc}" (${sameActionCount} veces). Forzando re-evaluaci\xF3n.`);
|
|
2947
|
+
history.push(`Turno ${stepCount}: \u{1F6D1} [AUTO-STOP] El click en "${desc}" fue bloqueado despu\xE9s de ${sameActionCount} repeticiones. Usa un IDX diferente o intenta hacer scroll para revelar el elemento. Si es un dropdown que no abre, usa interact_native_control.`);
|
|
2948
|
+
await page.waitForTimeout(800);
|
|
2887
2949
|
break;
|
|
2888
2950
|
}
|
|
2889
2951
|
}
|