@arcadialdev/arcality 3.0.1 → 3.0.3
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/README.md +12 -6
- package/bin/arcality.mjs +9 -8
- package/package.json +2 -1
- package/playwright.config.js +18 -16
- package/public/ArcalityImagen.png +0 -0
- package/public/logo-arcadial-blanco.png +0 -0
- package/public/logo.png +0 -0
- package/scripts/arcality-logs.mjs +167 -93
- package/scripts/gen-and-run.mjs +1706 -1158
- package/scripts/init.mjs +55 -19
- package/scripts/rebrand-report.mjs +16 -2
- package/scripts/setup.mjs +120 -166
- package/src/KnowledgeService.ts +29 -20
- package/src/arcalityClient.mjs +33 -63
- package/src/configLoader.mjs +35 -39
- package/src/configManager.mjs +48 -39
- package/src/playwrightAssets.mjs +27 -0
- package/src/services/collectiveMemoryService.ts +37 -26
- package/tests/_helpers/ArcalityReporter.js +1240 -712
- package/tests/_helpers/agentic-runner.bundle.spec.js +213 -140
|
@@ -28,6 +28,24 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
mod
|
|
29
29
|
));
|
|
30
30
|
|
|
31
|
+
// src/configManager.mjs
|
|
32
|
+
function isRealProjectId2(projectId) {
|
|
33
|
+
const id = String(projectId || "").trim();
|
|
34
|
+
if (!id)
|
|
35
|
+
return false;
|
|
36
|
+
if (id === "undefined" || id === "null")
|
|
37
|
+
return false;
|
|
38
|
+
if (/^(local|mock)_/i.test(id))
|
|
39
|
+
return false;
|
|
40
|
+
if (/^0{8}-0{4}-0{4}-0{4}-0{12}$/i.test(id))
|
|
41
|
+
return false;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
var init_configManager = __esm({
|
|
45
|
+
"src/configManager.mjs"() {
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
31
49
|
// src/configLoader.mjs
|
|
32
50
|
function getApiUrl() {
|
|
33
51
|
return "https://arcalityqadev.arcadial.lat";
|
|
@@ -63,6 +81,7 @@ var init_configLoader = __esm({
|
|
|
63
81
|
import_node_path = __toESM(require("node:path"), 1);
|
|
64
82
|
import_node_os = __toESM(require("node:os"), 1);
|
|
65
83
|
import_dotenv = __toESM(require("dotenv"), 1);
|
|
84
|
+
init_configManager();
|
|
66
85
|
import_dotenv.default.config();
|
|
67
86
|
CONFIG_DIR = import_node_path.default.join(import_node_os.default.homedir(), ".arcality");
|
|
68
87
|
CONFIG_FILE = import_node_path.default.join(CONFIG_DIR, "config.json");
|
|
@@ -80,44 +99,6 @@ __export(arcalityClient_exports, {
|
|
|
80
99
|
startMission: () => startMission,
|
|
81
100
|
validateApiKey: () => validateApiKey
|
|
82
101
|
});
|
|
83
|
-
function getTodayKey() {
|
|
84
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
85
|
-
}
|
|
86
|
-
function loadLocalUsage() {
|
|
87
|
-
try {
|
|
88
|
-
if (import_node_fs2.default.existsSync(USAGE_FILE)) {
|
|
89
|
-
return JSON.parse(import_node_fs2.default.readFileSync(USAGE_FILE, "utf8"));
|
|
90
|
-
}
|
|
91
|
-
} catch {
|
|
92
|
-
}
|
|
93
|
-
return {};
|
|
94
|
-
}
|
|
95
|
-
function saveLocalUsage(usage) {
|
|
96
|
-
try {
|
|
97
|
-
if (!import_node_fs2.default.existsSync(CONFIG_DIR)) {
|
|
98
|
-
import_node_fs2.default.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
99
|
-
}
|
|
100
|
-
import_node_fs2.default.writeFileSync(USAGE_FILE, JSON.stringify(usage, null, 2), "utf8");
|
|
101
|
-
} catch {
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
function getLocalDailyUsage() {
|
|
105
|
-
const usage = loadLocalUsage();
|
|
106
|
-
const today = getTodayKey();
|
|
107
|
-
return usage[today] || 0;
|
|
108
|
-
}
|
|
109
|
-
function incrementLocalUsage() {
|
|
110
|
-
const usage = loadLocalUsage();
|
|
111
|
-
const today = getTodayKey();
|
|
112
|
-
usage[today] = (usage[today] || 0) + 1;
|
|
113
|
-
const keys = Object.keys(usage).sort().reverse();
|
|
114
|
-
const cleaned = {};
|
|
115
|
-
for (const k of keys.slice(0, 7)) {
|
|
116
|
-
cleaned[k] = usage[k];
|
|
117
|
-
}
|
|
118
|
-
saveLocalUsage(cleaned);
|
|
119
|
-
return cleaned[today];
|
|
120
|
-
}
|
|
121
102
|
function loadArcalityConfig() {
|
|
122
103
|
try {
|
|
123
104
|
const configPath = import_node_path2.default.join(process.cwd(), "arcality.config");
|
|
@@ -143,17 +124,16 @@ function getEffectiveApiKey() {
|
|
|
143
124
|
}
|
|
144
125
|
function loadProjectId() {
|
|
145
126
|
const localConfig = loadArcalityConfig();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return process.env.ARCALITY_PROJECT_ID || null;
|
|
127
|
+
const projectId = localConfig?.projectId || process.env.ARCALITY_PROJECT_ID || null;
|
|
128
|
+
return isRealProjectId2(projectId) ? projectId : null;
|
|
149
129
|
}
|
|
150
130
|
async function validateApiKey() {
|
|
151
131
|
const key = getEffectiveApiKey();
|
|
152
132
|
if (!key) {
|
|
153
|
-
return { valid: false, error: "no_api_key", mode: "
|
|
133
|
+
return { valid: false, error: "no_api_key", mode: "live" };
|
|
154
134
|
}
|
|
155
135
|
if (!key.startsWith("arc_")) {
|
|
156
|
-
return { valid: false, error: "invalid_format", mode: "
|
|
136
|
+
return { valid: false, error: "invalid_format", mode: "live" };
|
|
157
137
|
}
|
|
158
138
|
const apiBase = getEffectiveApiBase();
|
|
159
139
|
if (apiBase) {
|
|
@@ -183,18 +163,11 @@ async function validateApiKey() {
|
|
|
183
163
|
return { ...data, valid: true, mode: "live" };
|
|
184
164
|
} catch (e) {
|
|
185
165
|
const reason = e?.name === "AbortError" ? "timeout (5s)" : e?.message || "unknown";
|
|
186
|
-
console.warn(
|
|
166
|
+
console.warn(`Backend not available (${apiBase}): ${reason}.`);
|
|
167
|
+
return { valid: false, error: "backend_unavailable", mode: "live", reason };
|
|
187
168
|
}
|
|
188
169
|
}
|
|
189
|
-
|
|
190
|
-
return {
|
|
191
|
-
valid: true,
|
|
192
|
-
mode: "mock",
|
|
193
|
-
plan: "internal",
|
|
194
|
-
daily_used: dailyUsed,
|
|
195
|
-
daily_limit: DAILY_MISSION_LIMIT,
|
|
196
|
-
remaining: Math.max(0, DAILY_MISSION_LIMIT - dailyUsed)
|
|
197
|
-
};
|
|
170
|
+
return { valid: false, error: "backend_unavailable", mode: "live" };
|
|
198
171
|
}
|
|
199
172
|
async function startMission(prompt, targetUrl) {
|
|
200
173
|
const key = getEffectiveApiKey();
|
|
@@ -204,6 +177,9 @@ async function startMission(prompt, targetUrl) {
|
|
|
204
177
|
if (apiBase) {
|
|
205
178
|
try {
|
|
206
179
|
const projectId = process.env.ARCALITY_PROJECT_ID || loadArcalityConfig()?.projectId;
|
|
180
|
+
if (!isRealProjectId2(projectId)) {
|
|
181
|
+
return { allowed: false, error: "no_project_id" };
|
|
182
|
+
}
|
|
207
183
|
const controller = new AbortController();
|
|
208
184
|
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
209
185
|
const res = await fetch(`${apiBase}/api/v1/missions/start`, {
|
|
@@ -230,32 +206,11 @@ async function startMission(prompt, targetUrl) {
|
|
|
230
206
|
return { allowed: true, ...await res.json() };
|
|
231
207
|
} catch (e) {
|
|
232
208
|
const reason = e?.name === "AbortError" ? "timeout (5s)" : e?.message || "unknown";
|
|
233
|
-
console.warn(
|
|
209
|
+
console.warn(`startMission failed (${apiBase}): ${reason}.`);
|
|
210
|
+
return { allowed: false, error: "backend_unavailable", reason };
|
|
234
211
|
}
|
|
235
212
|
}
|
|
236
|
-
|
|
237
|
-
if (dailyUsed >= DAILY_MISSION_LIMIT) {
|
|
238
|
-
const tomorrow = /* @__PURE__ */ new Date();
|
|
239
|
-
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
240
|
-
tomorrow.setHours(0, 0, 0, 0);
|
|
241
|
-
return {
|
|
242
|
-
allowed: false,
|
|
243
|
-
error: "mission_limit_exceeded",
|
|
244
|
-
daily_used: dailyUsed,
|
|
245
|
-
daily_limit: DAILY_MISSION_LIMIT,
|
|
246
|
-
remaining: 0,
|
|
247
|
-
resets_at: tomorrow.toISOString()
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
const newCount = incrementLocalUsage();
|
|
251
|
-
return {
|
|
252
|
-
allowed: true,
|
|
253
|
-
mode: "mock",
|
|
254
|
-
mission_id: `mock_${Date.now().toString(36)}`,
|
|
255
|
-
daily_used: newCount,
|
|
256
|
-
daily_limit: DAILY_MISSION_LIMIT,
|
|
257
|
-
remaining: DAILY_MISSION_LIMIT - newCount
|
|
258
|
-
};
|
|
213
|
+
return { allowed: false, error: "backend_unavailable" };
|
|
259
214
|
}
|
|
260
215
|
async function fetchMissions(projectId, tags) {
|
|
261
216
|
const key = getEffectiveApiKey();
|
|
@@ -263,7 +218,7 @@ async function fetchMissions(projectId, tags) {
|
|
|
263
218
|
return { success: false, error: "no_api_key", missions: [] };
|
|
264
219
|
const apiBase = getEffectiveApiBase();
|
|
265
220
|
if (!apiBase) {
|
|
266
|
-
return { success:
|
|
221
|
+
return { success: false, error: "backend_unavailable", missions: [] };
|
|
267
222
|
}
|
|
268
223
|
try {
|
|
269
224
|
const url = new URL(`${apiBase}/api/v1/projects/${projectId}/missions`);
|
|
@@ -295,8 +250,10 @@ async function fetchMissions(projectId, tags) {
|
|
|
295
250
|
}
|
|
296
251
|
async function endMission(missionId, result, usage = null, failReason = null, reportUrl = null, failReasoning = null) {
|
|
297
252
|
const apiBase = getEffectiveApiBase();
|
|
298
|
-
if (!apiBase
|
|
299
|
-
return { ok:
|
|
253
|
+
if (!apiBase)
|
|
254
|
+
return { ok: false, error: "backend_unavailable" };
|
|
255
|
+
if (!missionId)
|
|
256
|
+
return { ok: false, error: "no_mission_id" };
|
|
300
257
|
const key = getEffectiveApiKey();
|
|
301
258
|
try {
|
|
302
259
|
await fetch(`${apiBase}/api/v1/missions/${missionId}/end`, {
|
|
@@ -328,7 +285,7 @@ async function createAdoTask(title, description) {
|
|
|
328
285
|
return { success: false, error: "no_api_url" };
|
|
329
286
|
}
|
|
330
287
|
const projectId = loadProjectId();
|
|
331
|
-
if (!projectId) {
|
|
288
|
+
if (!isRealProjectId2(projectId)) {
|
|
332
289
|
if (process.env.DEBUG)
|
|
333
290
|
console.log(`[ADO] No hay Project ID configurado. Omitiendo creaci\xF3n de Task en Azure DevOps.`);
|
|
334
291
|
return { success: false, error: "no_project_id" };
|
|
@@ -377,7 +334,7 @@ async function createAdoTask(title, description) {
|
|
|
377
334
|
}
|
|
378
335
|
async function getEvidenceSasToken(missionId, projectId) {
|
|
379
336
|
const apiBase = getEffectiveApiBase();
|
|
380
|
-
if (!apiBase || !missionId)
|
|
337
|
+
if (!apiBase || !missionId || !isRealProjectId2(projectId))
|
|
381
338
|
return null;
|
|
382
339
|
const key = getEffectiveApiKey();
|
|
383
340
|
if (!key)
|
|
@@ -404,13 +361,13 @@ async function getEvidenceSasToken(missionId, projectId) {
|
|
|
404
361
|
return null;
|
|
405
362
|
}
|
|
406
363
|
}
|
|
407
|
-
var import_node_fs2, import_node_path2,
|
|
364
|
+
var import_node_fs2, import_node_path2, USAGE_FILE, ArcalityClient;
|
|
408
365
|
var init_arcalityClient = __esm({
|
|
409
366
|
"src/arcalityClient.mjs"() {
|
|
410
367
|
import_node_fs2 = __toESM(require("node:fs"), 1);
|
|
411
368
|
import_node_path2 = __toESM(require("node:path"), 1);
|
|
412
369
|
init_configLoader();
|
|
413
|
-
|
|
370
|
+
init_configManager();
|
|
414
371
|
USAGE_FILE = import_node_path2.default.join(CONFIG_DIR, "usage.json");
|
|
415
372
|
ArcalityClient = class {
|
|
416
373
|
constructor(apiKey) {
|
|
@@ -821,6 +778,18 @@ var path4 = __toESM(require("path"));
|
|
|
821
778
|
// src/KnowledgeService.ts
|
|
822
779
|
var crypto = __toESM(require("crypto"));
|
|
823
780
|
var import_chalk = __toESM(require("chalk"));
|
|
781
|
+
function isRealProjectId(projectId) {
|
|
782
|
+
const id = String(projectId || "").trim();
|
|
783
|
+
if (!id)
|
|
784
|
+
return false;
|
|
785
|
+
if (id === "undefined" || id === "null")
|
|
786
|
+
return false;
|
|
787
|
+
if (/^(local|mock)_/i.test(id))
|
|
788
|
+
return false;
|
|
789
|
+
if (/^0{8}-0{4}-0{4}-0{4}-0{12}$/i.test(id))
|
|
790
|
+
return false;
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
824
793
|
var KnowledgeService = class _KnowledgeService {
|
|
825
794
|
static instance;
|
|
826
795
|
apiBase;
|
|
@@ -859,10 +828,10 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
859
828
|
this.projectId = id;
|
|
860
829
|
}
|
|
861
830
|
getProjectId() {
|
|
862
|
-
if (!this.projectId
|
|
831
|
+
if (!isRealProjectId(this.projectId)) {
|
|
863
832
|
this.projectId = process.env.ARCALITY_PROJECT_ID || null;
|
|
864
833
|
}
|
|
865
|
-
return this.projectId;
|
|
834
|
+
return isRealProjectId(this.projectId) ? this.projectId : null;
|
|
866
835
|
}
|
|
867
836
|
/**
|
|
868
837
|
* 1. Gestión de Proyectos
|
|
@@ -877,7 +846,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
877
846
|
const data = await res.json();
|
|
878
847
|
return data.projects || [];
|
|
879
848
|
} catch (e) {
|
|
880
|
-
|
|
849
|
+
if (process.env.DEBUG)
|
|
850
|
+
console.warn(import_chalk.default.yellow(`[KnowledgeService] Error al obtener proyectos: ${e.message}`));
|
|
881
851
|
return [];
|
|
882
852
|
}
|
|
883
853
|
}
|
|
@@ -895,7 +865,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
895
865
|
return null;
|
|
896
866
|
return await res.json();
|
|
897
867
|
} catch (e) {
|
|
898
|
-
|
|
868
|
+
if (process.env.DEBUG)
|
|
869
|
+
console.error(import_chalk.default.red(`[KnowledgeService] Fall\xF3 creaci\xF3n de proyecto: ${e.message}`));
|
|
899
870
|
return null;
|
|
900
871
|
}
|
|
901
872
|
}
|
|
@@ -903,8 +874,9 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
903
874
|
* 2. Ingesta (Post-Percept)
|
|
904
875
|
*/
|
|
905
876
|
async ingest(payload) {
|
|
906
|
-
if (!payload.project_id
|
|
907
|
-
|
|
877
|
+
if (!isRealProjectId(payload.project_id)) {
|
|
878
|
+
if (process.env.DEBUG)
|
|
879
|
+
console.warn(import_chalk.default.yellow(`[Knowledge] Ingesta cancelada: project_id es inv\xE1lido.`));
|
|
908
880
|
return;
|
|
909
881
|
}
|
|
910
882
|
try {
|
|
@@ -925,7 +897,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
925
897
|
}
|
|
926
898
|
}
|
|
927
899
|
} catch (e) {
|
|
928
|
-
|
|
900
|
+
if (process.env.DEBUG)
|
|
901
|
+
console.warn(import_chalk.default.yellow(`[Knowledge] Error en ingesta: ${e.message}`));
|
|
929
902
|
}
|
|
930
903
|
}
|
|
931
904
|
/**
|
|
@@ -948,7 +921,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
948
921
|
return null;
|
|
949
922
|
return await res.json();
|
|
950
923
|
} catch (e) {
|
|
951
|
-
|
|
924
|
+
if (process.env.DEBUG)
|
|
925
|
+
console.warn(import_chalk.default.yellow(`[Knowledge] Error al obtener contexto: ${e.message}`));
|
|
952
926
|
return null;
|
|
953
927
|
}
|
|
954
928
|
}
|
|
@@ -977,7 +951,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
977
951
|
severity
|
|
978
952
|
})
|
|
979
953
|
});
|
|
980
|
-
|
|
954
|
+
if (process.env.DEBUG)
|
|
955
|
+
console.log(import_chalk.default.green(`[Knowledge] Nueva regla registrada: ${title}`));
|
|
981
956
|
} catch (e) {
|
|
982
957
|
}
|
|
983
958
|
}
|
|
@@ -1004,7 +979,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
1004
979
|
source: "agent_auto"
|
|
1005
980
|
})
|
|
1006
981
|
});
|
|
1007
|
-
|
|
982
|
+
if (process.env.DEBUG)
|
|
983
|
+
console.log(import_chalk.default.green(`[Knowledge] Nuevo campo catalogado: ${identifier}`));
|
|
1008
984
|
} catch (e) {
|
|
1009
985
|
}
|
|
1010
986
|
}
|
|
@@ -1031,7 +1007,8 @@ var KnowledgeService = class _KnowledgeService {
|
|
|
1031
1007
|
source: "agent_auto"
|
|
1032
1008
|
})
|
|
1033
1009
|
});
|
|
1034
|
-
|
|
1010
|
+
if (process.env.DEBUG)
|
|
1011
|
+
console.log(import_chalk.default.green(`[Knowledge] Nuevo conocimiento guardado: ${title}`));
|
|
1035
1012
|
} catch (e) {
|
|
1036
1013
|
}
|
|
1037
1014
|
}
|
|
@@ -1052,23 +1029,33 @@ var getOrgId = () => process.env.ARCALITY_ORG_ID;
|
|
|
1052
1029
|
var getMissionId = () => process.env.ARCALITY_MISSION_ID || EMPTY_GUID;
|
|
1053
1030
|
var EMPTY_GUID = "00000000-0000-0000-0000-000000000000";
|
|
1054
1031
|
var configWarningLogged = false;
|
|
1032
|
+
function hasRealProjectId(pid) {
|
|
1033
|
+
if (!pid || pid === EMPTY_GUID)
|
|
1034
|
+
return false;
|
|
1035
|
+
if (/^(local|mock)_/i.test(pid))
|
|
1036
|
+
return false;
|
|
1037
|
+
if (pid === "undefined" || pid === "null")
|
|
1038
|
+
return false;
|
|
1039
|
+
return true;
|
|
1040
|
+
}
|
|
1055
1041
|
function isConfigured() {
|
|
1056
1042
|
const base = getBase();
|
|
1057
1043
|
const key = getKey();
|
|
1058
1044
|
const pid = getPid();
|
|
1059
1045
|
const orgId = getOrgId();
|
|
1060
|
-
if (!base || !key || !pid ||
|
|
1046
|
+
if (!base || !key || !hasRealProjectId(pid) || !orgId) {
|
|
1061
1047
|
if (!configWarningLogged) {
|
|
1062
1048
|
const missing = [];
|
|
1063
1049
|
if (!base)
|
|
1064
1050
|
missing.push("ARCALITY_API_URL");
|
|
1065
1051
|
if (!key)
|
|
1066
1052
|
missing.push("ARCALITY_API_KEY");
|
|
1067
|
-
if (!pid
|
|
1053
|
+
if (!hasRealProjectId(pid))
|
|
1068
1054
|
missing.push("ARCALITY_PROJECT_ID");
|
|
1069
1055
|
if (!orgId)
|
|
1070
1056
|
missing.push("ARCALITY_ORG_ID");
|
|
1071
|
-
|
|
1057
|
+
if (process.env.DEBUG)
|
|
1058
|
+
console.warn(`[CollectiveMemory] Service disabled. Missing: ${missing.join(", ")}`);
|
|
1072
1059
|
configWarningLogged = true;
|
|
1073
1060
|
}
|
|
1074
1061
|
return false;
|
|
@@ -1188,8 +1175,10 @@ async function searchPromptPattern(prompt, limit = 5) {
|
|
|
1188
1175
|
prompt,
|
|
1189
1176
|
limit
|
|
1190
1177
|
};
|
|
1191
|
-
|
|
1192
|
-
|
|
1178
|
+
const debugPatternSearch = process.env.DEBUG === "true" || process.env.ARCALITY_DEBUG === "true";
|
|
1179
|
+
if (debugPatternSearch) {
|
|
1180
|
+
console.log(`[PatternSearch] POST ${apiUrl} | prompt_chars=${prompt.length} | limit=${limit}`);
|
|
1181
|
+
}
|
|
1193
1182
|
const res = await fetch(apiUrl, {
|
|
1194
1183
|
method: "POST",
|
|
1195
1184
|
headers: {
|
|
@@ -1199,15 +1188,19 @@ async function searchPromptPattern(prompt, limit = 5) {
|
|
|
1199
1188
|
body: JSON.stringify(payload)
|
|
1200
1189
|
});
|
|
1201
1190
|
if (!res.ok) {
|
|
1202
|
-
|
|
1191
|
+
if (debugPatternSearch)
|
|
1192
|
+
console.warn(`[PatternSearch] HTTP ${res.status} from ${apiUrl}`);
|
|
1203
1193
|
return [];
|
|
1204
1194
|
}
|
|
1205
1195
|
const data = await res.json();
|
|
1206
1196
|
const results = Array.isArray(data) ? data : data.matches || data.results || [];
|
|
1207
|
-
|
|
1197
|
+
if (debugPatternSearch)
|
|
1198
|
+
console.log(`[PatternSearch] ${results.length} patrones encontrados.`);
|
|
1208
1199
|
return results;
|
|
1209
1200
|
} catch (err) {
|
|
1210
|
-
|
|
1201
|
+
if (process.env.DEBUG === "true" || process.env.ARCALITY_DEBUG === "true") {
|
|
1202
|
+
console.warn(`[PatternSearch] Error buscando patrones: ${err?.message || "unknown"}`);
|
|
1203
|
+
}
|
|
1211
1204
|
return [];
|
|
1212
1205
|
}
|
|
1213
1206
|
}
|
|
@@ -2261,10 +2254,12 @@ ${relevantFailures.map((m) => `- ${m.prompt}`).join("\n")}
|
|
|
2261
2254
|
contextData.fields.forEach((f) => memoryBackendContext += `- ${f.field_identifier} (${f.field_type}) - Required: ${f.is_required}
|
|
2262
2255
|
`);
|
|
2263
2256
|
}
|
|
2264
|
-
|
|
2257
|
+
if (process.env.DEBUG)
|
|
2258
|
+
console.log(`>>ARCALITY_STATUS>> \u{1F9E0} Contexto de Memoria Colectiva inyectado (${contextData.rules?.length || 0} reglas, ${contextData.fields?.length || 0} campos).`);
|
|
2265
2259
|
}
|
|
2266
2260
|
} catch (e) {
|
|
2267
|
-
|
|
2261
|
+
if (process.env.DEBUG)
|
|
2262
|
+
console.log(`>>ARCALITY_STATUS>> \u26A0\uFE0F Error en hook de contexto: ${e.message}`);
|
|
2268
2263
|
}
|
|
2269
2264
|
let customUserContext = "";
|
|
2270
2265
|
try {
|
|
@@ -3445,6 +3440,31 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3445
3440
|
}).catch(() => {
|
|
3446
3441
|
});
|
|
3447
3442
|
}
|
|
3443
|
+
async function readLocatorText(locator) {
|
|
3444
|
+
const textContent = await locator.textContent().catch(() => null);
|
|
3445
|
+
if (typeof textContent === "string") {
|
|
3446
|
+
const normalized = textContent.trim();
|
|
3447
|
+
if (normalized)
|
|
3448
|
+
return normalized;
|
|
3449
|
+
}
|
|
3450
|
+
const innerText = await locator.innerText().catch(() => "");
|
|
3451
|
+
return typeof innerText === "string" ? innerText.trim() : "";
|
|
3452
|
+
}
|
|
3453
|
+
function writeBatchMissionResult(payload) {
|
|
3454
|
+
const runDomainDir = process.env.ARCALITY_RUN_DOMAIN_DIR;
|
|
3455
|
+
if (!runDomainDir)
|
|
3456
|
+
return;
|
|
3457
|
+
try {
|
|
3458
|
+
if (!fs5.existsSync(runDomainDir)) {
|
|
3459
|
+
fs5.mkdirSync(runDomainDir, { recursive: true });
|
|
3460
|
+
}
|
|
3461
|
+
fs5.writeFileSync(
|
|
3462
|
+
path5.join(runDomainDir, "mission-result.json"),
|
|
3463
|
+
JSON.stringify(payload, null, 2)
|
|
3464
|
+
);
|
|
3465
|
+
} catch {
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3448
3468
|
(0, import_test.test)("Arcality AI Runner", async ({ page }, testInfo) => {
|
|
3449
3469
|
import_test.test.setTimeout(12e5);
|
|
3450
3470
|
const contextDir = process.env.CONTEXT_DIR || "out";
|
|
@@ -3588,15 +3608,55 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3588
3608
|
};
|
|
3589
3609
|
memories.push(missionData);
|
|
3590
3610
|
fs5.writeFileSync(memoryFile2, JSON.stringify(memories, null, 2));
|
|
3591
|
-
|
|
3611
|
+
if (process.env.DEBUG)
|
|
3612
|
+
console.log(`>>ARCALITY_STATUS>> \u{1F9E0} Memoria guardada: ${cleanSteps.length} pasos limpios (${rawSteps.length - cleanSteps.length} corruptos filtrados)`);
|
|
3592
3613
|
} catch (err) {
|
|
3593
3614
|
console.error("\u274C Fall\xF3 al guardar memoria:", err);
|
|
3594
3615
|
}
|
|
3595
3616
|
try {
|
|
3596
|
-
const
|
|
3597
|
-
|
|
3617
|
+
const timestampIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
3618
|
+
const timestampMs = Date.now();
|
|
3619
|
+
const summaryPayload = {
|
|
3620
|
+
prompt,
|
|
3621
|
+
history,
|
|
3622
|
+
steps: stepCount,
|
|
3623
|
+
success: finalSuccess,
|
|
3624
|
+
error: hasCriticalError,
|
|
3625
|
+
fail_reason: failReason,
|
|
3626
|
+
fail_reasoning: failReasoning,
|
|
3627
|
+
usage: totalMissionUsage,
|
|
3628
|
+
target: process.env.BASE_URL || "",
|
|
3629
|
+
target_path: process.env.TARGET_PATH || "",
|
|
3630
|
+
report_dir: process.env.REPORTS_DIR || "",
|
|
3631
|
+
timestamp: timestampIso
|
|
3632
|
+
};
|
|
3633
|
+
const logPath = path5.join(contextDir, `agent-log-${timestampMs}.json`);
|
|
3634
|
+
fs5.writeFileSync(logPath, JSON.stringify(summaryPayload, null, 2));
|
|
3635
|
+
const runDomainDir = process.env.ARCALITY_RUN_DOMAIN_DIR || path5.dirname(contextDir);
|
|
3636
|
+
const durableLogsDir = path5.join(runDomainDir, "logs");
|
|
3637
|
+
fs5.mkdirSync(durableLogsDir, { recursive: true });
|
|
3638
|
+
fs5.writeFileSync(
|
|
3639
|
+
path5.join(durableLogsDir, `mission-log-${timestampMs}.json`),
|
|
3640
|
+
JSON.stringify(summaryPayload, null, 2)
|
|
3641
|
+
);
|
|
3642
|
+
writeBatchMissionResult(summaryPayload);
|
|
3598
3643
|
try {
|
|
3599
|
-
|
|
3644
|
+
const historyLine = JSON.stringify({
|
|
3645
|
+
ts: timestampIso,
|
|
3646
|
+
mission: prompt.substring(0, 150),
|
|
3647
|
+
success: finalSuccess,
|
|
3648
|
+
steps: stepCount,
|
|
3649
|
+
fail_reason: failReason,
|
|
3650
|
+
report_dir: process.env.REPORTS_DIR || ""
|
|
3651
|
+
}) + "\n";
|
|
3652
|
+
fs5.appendFileSync(
|
|
3653
|
+
path5.join(contextDir, "arcality-history.log"),
|
|
3654
|
+
historyLine
|
|
3655
|
+
);
|
|
3656
|
+
fs5.appendFileSync(
|
|
3657
|
+
path5.join(durableLogsDir, "arcality-history.log"),
|
|
3658
|
+
historyLine
|
|
3659
|
+
);
|
|
3600
3660
|
} catch (e) {
|
|
3601
3661
|
}
|
|
3602
3662
|
} catch (err) {
|
|
@@ -3618,7 +3678,8 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3618
3678
|
return;
|
|
3619
3679
|
}
|
|
3620
3680
|
if (!isFailed && stepsData.length === 0 && stepsDataBackup.length === 0) {
|
|
3621
|
-
|
|
3681
|
+
if (process.env.DEBUG)
|
|
3682
|
+
console.warn(`[CollectiveMemory] \u26A0\uFE0F stepsData vac\xEDo en path de \xE9xito \u2014 intentando usar backup...`);
|
|
3622
3683
|
}
|
|
3623
3684
|
const baseSteps = stepsData.length > 0 ? stepsData : stepsDataBackup;
|
|
3624
3685
|
const effectiveSteps = baseSteps.filter((step) => {
|
|
@@ -3629,11 +3690,15 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3629
3690
|
}
|
|
3630
3691
|
return true;
|
|
3631
3692
|
});
|
|
3632
|
-
|
|
3693
|
+
if (process.env.DEBUG)
|
|
3694
|
+
console.log(`
|
|
3633
3695
|
======================================================`);
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3696
|
+
if (process.env.DEBUG)
|
|
3697
|
+
console.log(`\u{1F9E0} [ARCHIVE SUBSYSTEM - KNOWLEDGE INGESTION]`);
|
|
3698
|
+
if (process.env.DEBUG)
|
|
3699
|
+
console.log(`>>arcality>> Saving telemetry (project: ${pid}, steps: ${effectiveSteps.length}, isFailed: ${isFailed})...`);
|
|
3700
|
+
if (process.env.DEBUG)
|
|
3701
|
+
console.log(`======================================================
|
|
3637
3702
|
`);
|
|
3638
3703
|
try {
|
|
3639
3704
|
const stepsNarrative = effectiveSteps.map((s) => `${s.action_data?.action || "action"} "${s.componentName}" en ${s.url}`).join(" \u2192 ").substring(0, 500);
|
|
@@ -3644,9 +3709,9 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3644
3709
|
title: `Flujo exitoso: ${prompt.substring(0, 100)}`,
|
|
3645
3710
|
content: stepsNarrative || prompt.substring(0, 500)
|
|
3646
3711
|
});
|
|
3647
|
-
if (knowledgeId)
|
|
3712
|
+
if (process.env.DEBUG && knowledgeId)
|
|
3648
3713
|
console.log(`\u{1F9E0} [COLLECTIVE MEMORY] \u2705 Knowledge guardado: ${knowledgeId}`);
|
|
3649
|
-
else
|
|
3714
|
+
else if (process.env.DEBUG)
|
|
3650
3715
|
console.warn(`[CollectiveMemory] \u26A0\uFE0F pushKnowledge retorn\xF3 null (revisar HTTP status arriba)`);
|
|
3651
3716
|
const uniqueUrls = [...new Set(effectiveSteps.map((s) => s.url).filter(Boolean))];
|
|
3652
3717
|
if (uniqueUrls.length > 1) {
|
|
@@ -3656,7 +3721,7 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3656
3721
|
description: `Arcality naveg\xF3 ${uniqueUrls.length} p\xE1ginas: ${uniqueUrls.join(" \u2192 ").substring(0, 400)}`,
|
|
3657
3722
|
severity: "suggestion"
|
|
3658
3723
|
});
|
|
3659
|
-
if (ruleId)
|
|
3724
|
+
if (process.env.DEBUG && ruleId)
|
|
3660
3725
|
console.log(`\u{1F9E0} [COLLECTIVE MEMORY] \u2705 Regla NAVIGATION guardada: ${ruleId}`);
|
|
3661
3726
|
}
|
|
3662
3727
|
const submitStep = effectiveSteps.find(
|
|
@@ -3669,7 +3734,7 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3669
3734
|
description: `Flujo exitoso incluy\xF3 guardado/creaci\xF3n. Pasos: ${stepsNarrative.substring(0, 400)}`,
|
|
3670
3735
|
severity: "important"
|
|
3671
3736
|
});
|
|
3672
|
-
if (ruleId2)
|
|
3737
|
+
if (process.env.DEBUG && ruleId2)
|
|
3673
3738
|
console.log(`\u{1F9E0} [COLLECTIVE MEMORY] \u2705 Regla UI_UX guardada: ${ruleId2}`);
|
|
3674
3739
|
}
|
|
3675
3740
|
} else {
|
|
@@ -3679,13 +3744,14 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3679
3744
|
description: `Arcality no pudo completar: "${prompt.substring(0, 200)}". \xDAltimos pasos: ${stepsNarrative.substring(0, 300)}`,
|
|
3680
3745
|
severity: "important"
|
|
3681
3746
|
});
|
|
3682
|
-
if (failRuleId)
|
|
3747
|
+
if (process.env.DEBUG && failRuleId)
|
|
3683
3748
|
console.log(`\u{1F9E0} [COLLECTIVE MEMORY] \u2705 Regla de fallo guardada: ${failRuleId}`);
|
|
3684
|
-
else
|
|
3749
|
+
else if (process.env.DEBUG)
|
|
3685
3750
|
console.warn(`[CollectiveMemory] \u26A0\uFE0F No se pudo persistir misi\xF3n fallida`);
|
|
3686
3751
|
}
|
|
3687
3752
|
} catch (err) {
|
|
3688
|
-
|
|
3753
|
+
if (process.env.DEBUG)
|
|
3754
|
+
console.warn(`[CollectiveMemory] \u274C Error inesperado en persistCollectiveMemory: ${err?.message}`);
|
|
3689
3755
|
}
|
|
3690
3756
|
};
|
|
3691
3757
|
console.log(`
|
|
@@ -3750,7 +3816,8 @@ function captureValidationRule(errorMessage, context) {
|
|
|
3750
3816
|
const matches = promptKeywords.filter((kw) => patternKeywords.some((pkw) => pkw.includes(kw) || kw.includes(pkw))).length;
|
|
3751
3817
|
const isVectorMatch = true;
|
|
3752
3818
|
if (isVectorMatch) {
|
|
3753
|
-
|
|
3819
|
+
if (process.env.DEBUG)
|
|
3820
|
+
console.log(`>>ARCALITY_STATUS>> \u{1F9E0} Memoria Colectiva detectada (id: ${bestMatch.id}). Descargando a memoria local...`);
|
|
3754
3821
|
reusedPatternId = bestMatch.id || "unknown";
|
|
3755
3822
|
let patternJsonObj = {};
|
|
3756
3823
|
try {
|
|
@@ -3869,7 +3936,7 @@ ${readableHistory}`;
|
|
|
3869
3936
|
let foundSuccessToast = false;
|
|
3870
3937
|
for (const el of feedbackEls) {
|
|
3871
3938
|
if (await el.isVisible().catch(() => false)) {
|
|
3872
|
-
const txt = await el
|
|
3939
|
+
const txt = await readLocatorText(el);
|
|
3873
3940
|
if (successKeywords.test(txt.toLowerCase())) {
|
|
3874
3941
|
foundSuccessToast = true;
|
|
3875
3942
|
console.log(`>>ARCALITY_STATUS>> \u2728 Auto-Success: Toast de \xE9xito detectado: "${txt.substring(0, 60)}"`);
|
|
@@ -3894,7 +3961,7 @@ ${readableHistory}`;
|
|
|
3894
3961
|
if (btnCount > 0) {
|
|
3895
3962
|
const firstBtn = finalSaveBtn.first();
|
|
3896
3963
|
if (await firstBtn.isVisible().catch(() => false) && await firstBtn.isEnabled().catch(() => false)) {
|
|
3897
|
-
const btnText = await firstBtn
|
|
3964
|
+
const btnText = await readLocatorText(firstBtn);
|
|
3898
3965
|
const isModalOpen = await page.locator('[role="dialog"], .modal, .mat-dialog-container').first().isVisible().catch(() => false);
|
|
3899
3966
|
if (!isModalOpen) {
|
|
3900
3967
|
console.log(`
|
|
@@ -3907,7 +3974,7 @@ ${readableHistory}`;
|
|
|
3907
3974
|
let proactiveSuccess = false;
|
|
3908
3975
|
for (const fb of postSaveFb) {
|
|
3909
3976
|
if (await fb.isVisible().catch(() => false)) {
|
|
3910
|
-
const fbTxt = await fb
|
|
3977
|
+
const fbTxt = await readLocatorText(fb);
|
|
3911
3978
|
if (successKeywords.test(fbTxt)) {
|
|
3912
3979
|
console.log(`>>ARCALITY_STATUS>> \u2728 [PROACTIVE FINISH] \xC9xito confirmado por toast: "${fbTxt.substring(0, 60)}"`);
|
|
3913
3980
|
proactiveSuccess = true;
|
|
@@ -3933,7 +4000,7 @@ ${readableHistory}`;
|
|
|
3933
4000
|
const initialToasts = await page.locator('.toast, .alert, [role="status"], [role="alert"]').all();
|
|
3934
4001
|
for (const t of initialToasts) {
|
|
3935
4002
|
if (await t.isVisible().catch(() => false)) {
|
|
3936
|
-
lastSeenSuccessToast = await t
|
|
4003
|
+
lastSeenSuccessToast = await readLocatorText(t);
|
|
3937
4004
|
if (lastSeenSuccessToast)
|
|
3938
4005
|
console.log(`>>ARCALITY_STATUS>> \u{1F4A1} Nota: Ignorando mensaje preexistente: "${lastSeenSuccessToast.substring(0, 30)}..."`);
|
|
3939
4006
|
}
|
|
@@ -3967,7 +4034,7 @@ Detalles de la excepci\xF3n en consola: ${jsError}`;
|
|
|
3967
4034
|
const systemToastEls = await page.locator('.toast, .alert, [role="alert"], [role="status"], .snackbar, .notification, .error-message, .mat-snack-bar-container').all();
|
|
3968
4035
|
for (const el of systemToastEls) {
|
|
3969
4036
|
if (await el.isVisible().catch(() => false)) {
|
|
3970
|
-
const sysErrTxt = await el
|
|
4037
|
+
const sysErrTxt = await readLocatorText(el);
|
|
3971
4038
|
if (sysErrTxt && systemErrorKeywords.test(sysErrTxt)) {
|
|
3972
4039
|
console.error(`
|
|
3973
4040
|
\u{1F6D1} [SYSTEM ERROR DETECTADO] El portal report\xF3 un error de sistema no recuperable en UI:`);
|
|
@@ -3992,7 +4059,7 @@ Detalles de la excepci\xF3n en consola: ${jsError}`;
|
|
|
3992
4059
|
const errorEls = await page.locator('.toast, .alert, [role="alert"], [role="status"], .snackbar, .notification, .error-message, .mat-snack-bar-container, [class*="alert"], [class*="toast"]').all();
|
|
3993
4060
|
for (const el of errorEls) {
|
|
3994
4061
|
if (await el.isVisible().catch(() => false)) {
|
|
3995
|
-
const errTxt = await el
|
|
4062
|
+
const errTxt = await readLocatorText(el);
|
|
3996
4063
|
if (errTxt && failureKeywords.test(errTxt.toLowerCase())) {
|
|
3997
4064
|
hasVisibleError = true;
|
|
3998
4065
|
break;
|
|
@@ -4022,7 +4089,7 @@ Detalles de la excepci\xF3n en consola: ${jsError}`;
|
|
|
4022
4089
|
const errorEls = await page.locator('.toast, .alert, [role="alert"], [role="status"], .snackbar, .notification, .error-message, .mat-snack-bar-container, [class*="alert"], [class*="toast"]').all();
|
|
4023
4090
|
for (const el of errorEls) {
|
|
4024
4091
|
if (await el.isVisible().catch(() => false)) {
|
|
4025
|
-
const errTxt = await el
|
|
4092
|
+
const errTxt = await readLocatorText(el);
|
|
4026
4093
|
if (errTxt && failureKeywords.test(errTxt.toLowerCase())) {
|
|
4027
4094
|
const isDuplicateError = /repetido|duplicado|ya existe|already exists/i.test(errTxt);
|
|
4028
4095
|
const correctionHint = isDuplicateError ? `\u{1F6D1} ACCI\xD3N REQUERIDA: El valor que ingresaste ya existe en el sistema. DEBES regresar al campo que caus\xF3 el error y cambiar su valor por uno \xDANICO (agrega un sufijo como _${Date.now().toString().slice(-4)} o un n\xFAmero aleatorio). NO intentes guardar sin cambiar el valor primero.` : `\u{1F6D1} ANOMAL\xCDA UI DETECTADA: El sistema mostr\xF3 un error de validaci\xF3n. DIRECTIVA PARA ARCALITY: Si este error significa que la misi\xF3n no puede completarse (ej. un bug del sistema o un estado bloqueado), DEBES usar 'finish: true' inmediatamente y explicar el problema. Si es un simple error de formato de datos, corrige los datos y reintenta.`;
|
|
@@ -4196,7 +4263,7 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4196
4263
|
const isCriticalSuccess = textLower.includes("exitosamente") || textLower.includes("guardado") || textLower.includes("creado") || textLower.includes("success") || textLower.includes("correctamente") || textLower.includes("misi\xF3n cumplida");
|
|
4197
4264
|
const isCriticalFeedback = isCriticalFailure || isCriticalSuccess;
|
|
4198
4265
|
if (!isCriticalFeedback && step.type && ["span", "p", "label", "i", "svg", "img"].includes(step.type)) {
|
|
4199
|
-
const elementText = await loc
|
|
4266
|
+
const elementText = await readLocatorText(loc);
|
|
4200
4267
|
const elementTextLower = elementText.toLowerCase();
|
|
4201
4268
|
if (failureKeywords.test(elementTextLower)) {
|
|
4202
4269
|
console.log(`>>ARCALITY_STATUS>> \u26A0\uFE0F Feedback de ERROR en elemento peque\xF1o: "${elementTextLower.substring(0, 50)}..."`);
|
|
@@ -4288,7 +4355,7 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4288
4355
|
let foundSuccessPost = false;
|
|
4289
4356
|
for (const fb of postSubmitFeedback) {
|
|
4290
4357
|
if (await fb.isVisible().catch(() => false)) {
|
|
4291
|
-
const fbText = await fb
|
|
4358
|
+
const fbText = await readLocatorText(fb);
|
|
4292
4359
|
const postSuccessKw = /exitosamente|creado correctamente|guardado correctamente|operación exitosa|registro guardado|saved successfully|created successfully/i;
|
|
4293
4360
|
if (postSuccessKw.test(fbText)) {
|
|
4294
4361
|
console.log(`>>ARCALITY_STATUS>> \u2728 \xC9xito visual detectado en toast: "${fbText.substring(0, 60)}"`);
|
|
@@ -4341,7 +4408,7 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4341
4408
|
let hasPostNavError = false;
|
|
4342
4409
|
for (const alertEl of postNavAlerts) {
|
|
4343
4410
|
if (await alertEl.isVisible().catch(() => false)) {
|
|
4344
|
-
const alertTxt = await alertEl
|
|
4411
|
+
const alertTxt = await readLocatorText(alertEl);
|
|
4345
4412
|
if (failureKeywords.test(alertTxt.toLowerCase())) {
|
|
4346
4413
|
hasPostNavError = true;
|
|
4347
4414
|
console.log(`>>ARCALITY_STATUS>> \u26A0\uFE0F Error en alerta post-guardado: "${alertTxt.substring(0, 60)}"`);
|
|
@@ -4413,7 +4480,7 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4413
4480
|
const panels = await page.locator("igc-dockmanager [slot]").all();
|
|
4414
4481
|
let emptyPanelCount = 0;
|
|
4415
4482
|
for (const panel of panels.slice(0, 6)) {
|
|
4416
|
-
const txt =
|
|
4483
|
+
const txt = await readLocatorText(panel);
|
|
4417
4484
|
const isVisible = await panel.isVisible().catch(() => false);
|
|
4418
4485
|
if (isVisible && txt.length < 10)
|
|
4419
4486
|
emptyPanelCount++;
|
|
@@ -4534,7 +4601,8 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4534
4601
|
}
|
|
4535
4602
|
if (response.finish) {
|
|
4536
4603
|
if (!containsError) {
|
|
4537
|
-
|
|
4604
|
+
if (process.env.DEBUG)
|
|
4605
|
+
console.log(">>ARCALITY_STATUS>> \u2705 Arcality solicit\xF3 finalizar misi\xF3n.");
|
|
4538
4606
|
isFinished = true;
|
|
4539
4607
|
if (!response.actions || response.actions.length === 0) {
|
|
4540
4608
|
stepsData.push({
|
|
@@ -4554,7 +4622,7 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4554
4622
|
let hasVisibleFailure = false;
|
|
4555
4623
|
for (const el of finishFeedbackEls) {
|
|
4556
4624
|
if (await el.isVisible().catch(() => false)) {
|
|
4557
|
-
const txt = await el
|
|
4625
|
+
const txt = await readLocatorText(el);
|
|
4558
4626
|
if (failureKeywords.test(txt.toLowerCase())) {
|
|
4559
4627
|
hasVisibleFailure = true;
|
|
4560
4628
|
console.log(`>>ARCALITY_STATUS>> \u26A0\uFE0F Error detectado en toast/alerta: "${txt.substring(0, 60)}"`);
|
|
@@ -4592,8 +4660,10 @@ Acci\xF3n bloqueada: Bucle de tipo ${loopType} sobre los elementos ${Array.from(
|
|
|
4592
4660
|
if (stepCount > 2) {
|
|
4593
4661
|
const allFeedback = await feedbackLocator.all();
|
|
4594
4662
|
for (const fb of allFeedback) {
|
|
4595
|
-
if (await fb.isVisible()) {
|
|
4596
|
-
const rawTxt = await fb
|
|
4663
|
+
if (await fb.isVisible().catch(() => false)) {
|
|
4664
|
+
const rawTxt = await readLocatorText(fb);
|
|
4665
|
+
if (!rawTxt)
|
|
4666
|
+
continue;
|
|
4597
4667
|
const txt = rawTxt.toLowerCase();
|
|
4598
4668
|
if (systemErrorKeywords.test(rawTxt)) {
|
|
4599
4669
|
console.error(`
|
|
@@ -4735,7 +4805,8 @@ Evidence: ${JSON.stringify(v.evidence).substring(0, 400)}`,
|
|
|
4735
4805
|
});
|
|
4736
4806
|
}
|
|
4737
4807
|
} catch (e) {
|
|
4738
|
-
|
|
4808
|
+
if (process.env.DEBUG)
|
|
4809
|
+
console.warn(">>ARCALITY_STATUS>> \u26A0\uFE0F Fall\xF3 persistir hallazgos de seguridad en Memoria Colectiva.");
|
|
4739
4810
|
}
|
|
4740
4811
|
} else {
|
|
4741
4812
|
console.log(`>>ARCALITY_STATUS>> \u{1F6E1}\uFE0F Escaneo de seguridad completado. No se encontraron problemas.`);
|
|
@@ -4754,7 +4825,8 @@ Evidence: ${JSON.stringify(v.evidence).substring(0, 400)}`,
|
|
|
4754
4825
|
}
|
|
4755
4826
|
saveMissionResults();
|
|
4756
4827
|
if (!aiMarkedSuccess) {
|
|
4757
|
-
|
|
4828
|
+
if (process.env.DEBUG)
|
|
4829
|
+
console.log(`>>ARCALITY_STATUS>> \u{1F4CA} Uso total de tokens esta misi\xF3n: IN=${totalMissionUsage.input_tokens} | OUT=${totalMissionUsage.output_tokens} | Cache writes=${totalMissionUsage.cache_creation_input_tokens} | Cache reads=${totalMissionUsage.cache_read_input_tokens}`);
|
|
4758
4830
|
await persistCollectiveMemory(true).catch(() => {
|
|
4759
4831
|
});
|
|
4760
4832
|
let finalErrorMsg = `Misi\xF3n no completada o finalizada con errores.
|
|
@@ -4773,7 +4845,8 @@ ${failReasoning}
|
|
|
4773
4845
|
`;
|
|
4774
4846
|
throw new Error(finalErrorMsg);
|
|
4775
4847
|
} else {
|
|
4776
|
-
|
|
4848
|
+
if (process.env.DEBUG)
|
|
4849
|
+
console.log(`>>ARCALITY_STATUS>> \u{1F4CA} Uso total de tokens esta misi\xF3n: IN=${totalMissionUsage.input_tokens} | OUT=${totalMissionUsage.output_tokens} | Cache writes=${totalMissionUsage.cache_creation_input_tokens} | Cache reads=${totalMissionUsage.cache_read_input_tokens}`);
|
|
4777
4850
|
}
|
|
4778
4851
|
if (fs5.existsSync(contextDir)) {
|
|
4779
4852
|
try {
|