social-agent-cli 1.8.2 → 1.9.0
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/ai/mapper.ts +6 -2
- package/ai/runner.ts +38 -32
- package/package.json +1 -1
package/ai/mapper.ts
CHANGED
|
@@ -235,7 +235,11 @@ ${domSnapshot}
|
|
|
235
235
|
Kurallar:
|
|
236
236
|
- ARIA snapshot'taki role ve name bilgilerini kullanarak selector oluştur
|
|
237
237
|
- aria-label, role, data-testid, id tercih et
|
|
238
|
-
- Dosya/görsel/video yükleme için "upload" action kullan
|
|
238
|
+
- Dosya/görsel/video yükleme için "upload" action kullan. Upload action şöyle çalışır:
|
|
239
|
+
- selector'da medya/fotoğraf ekleme BUTONUNU ver (ör: button[aria-label*='Fotoğraf'], button[aria-label*='Add media'])
|
|
240
|
+
- Sistem butona tıklayıp fileChooser'ı yakalayacak ve dosyayı programatik olarak set edecek, file picker açılmayacak
|
|
241
|
+
- Eğer selector verilmezse sayfadaki input[type=file]'a direkt set eder
|
|
242
|
+
- value alanına {{IMAGE}} yaz
|
|
239
243
|
- Her adım için 2+ fallback selector
|
|
240
244
|
- Parametreler için placeholder kullan: {{CONTENT}} = metin, {{USERNAME}} = kullanıcı adı, {{URL}} = link, vs.
|
|
241
245
|
- Hangi parametreleri kullandığını "parameters" alanında listele
|
|
@@ -342,7 +346,7 @@ GÖREV: Ekranın mevcut durumunu analiz et. Amaca ulaşmak için kalan adımlar
|
|
|
342
346
|
- Belki farklı bir yol izlenmeli
|
|
343
347
|
- {{CONTENT}} = post metni placeholder'ı
|
|
344
348
|
- data-testid, aria-label, role tercih et, her adıma 2+ fallback selector ver
|
|
345
|
-
- Dosya yükleme için "upload" action kullan
|
|
349
|
+
- Dosya yükleme için "upload" action kullan. selector'a medya ekleme butonunu ver, value: {{IMAGE}}`;
|
|
346
350
|
|
|
347
351
|
console.log(`\n[heal] AI ekranı analiz ediyor (effort: ${effort})...\n`);
|
|
348
352
|
|
package/ai/runner.ts
CHANGED
|
@@ -84,35 +84,7 @@ export async function runCommand(
|
|
|
84
84
|
|
|
85
85
|
let steps = [...map.steps];
|
|
86
86
|
|
|
87
|
-
// IMAGE parametresi var ama map'te upload
|
|
88
|
-
if (imageParam && !steps.some(s => s.action === "upload")) {
|
|
89
|
-
// Gönder butonunun index'ini bul (genelde son click)
|
|
90
|
-
const sendIdx = steps.findLastIndex((s: any) => s.action === "click" && s.description?.toLowerCase().match(/gönder|post|tweet|paylaş|send|submit/));
|
|
91
|
-
if (sendIdx > -1) {
|
|
92
|
-
steps.splice(sendIdx, 0,
|
|
93
|
-
{
|
|
94
|
-
action: "upload" as const,
|
|
95
|
-
description: "Görsel yükle",
|
|
96
|
-
selector: "input[type='file']",
|
|
97
|
-
value: "{{IMAGE}}",
|
|
98
|
-
fallbackSelectors: ["[data-testid='fileInput']", "input[accept*='image']", "input[type='file'][accept]"],
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
action: "wait" as const,
|
|
102
|
-
description: "Görsel yüklenmesini bekle",
|
|
103
|
-
waitMs: 2000,
|
|
104
|
-
}
|
|
105
|
-
);
|
|
106
|
-
console.log(` [auto] Görsel yükleme adımı eklendi (map'e kaydedilecek)`);
|
|
107
|
-
|
|
108
|
-
// Map'i güncelle - sonraki isteklerde de kullanılsın
|
|
109
|
-
const { saveMap } = await import("./mapper.js");
|
|
110
|
-
map.steps = steps;
|
|
111
|
-
map.parameters = [...(map.parameters || []), "{{IMAGE}}"];
|
|
112
|
-
map.version++;
|
|
113
|
-
saveMap(map);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
87
|
+
// IMAGE parametresi var ama map'te upload yok → planner learn_new ile öğretecek
|
|
116
88
|
let stepIdx = 0;
|
|
117
89
|
let healAttempt = 0;
|
|
118
90
|
|
|
@@ -327,10 +299,44 @@ async function executeMapStep(
|
|
|
327
299
|
const filePath = rp(step.value || "{{IMAGE}}");
|
|
328
300
|
if (!filePath || filePath.includes("{{")) break; // dosya yoksa atla
|
|
329
301
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
302
|
+
let uploaded = false;
|
|
303
|
+
|
|
304
|
+
// 1. Selector varsa önce o butona tıkla (medya butonu gibi) ve fileChooser yakala
|
|
305
|
+
if (selectors.length > 0 && !selectors[0].includes("input[type")) {
|
|
306
|
+
for (const sel of selectors) {
|
|
307
|
+
try {
|
|
308
|
+
const [fileChooser] = await Promise.all([
|
|
309
|
+
page.waitForEvent("filechooser", { timeout: 5000 }),
|
|
310
|
+
page.click(sel),
|
|
311
|
+
]);
|
|
312
|
+
await fileChooser.setFiles(filePath);
|
|
313
|
+
uploaded = true;
|
|
314
|
+
break;
|
|
315
|
+
} catch {}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// 2. Sayfadaki input[type=file]'a direkt set et
|
|
320
|
+
if (!uploaded) {
|
|
321
|
+
try {
|
|
322
|
+
const fileInput = page.locator('input[type="file"]').first();
|
|
323
|
+
await fileInput.waitFor({ timeout: 3000 });
|
|
324
|
+
await fileInput.setInputFiles(filePath);
|
|
325
|
+
uploaded = true;
|
|
326
|
+
} catch {}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// 3. Tüm input[type=file]'ları dene
|
|
330
|
+
if (!uploaded) {
|
|
331
|
+
try {
|
|
332
|
+
const inputs = await page.locator('input[type="file"]').all();
|
|
333
|
+
for (const input of inputs) {
|
|
334
|
+
try { await input.setInputFiles(filePath); uploaded = true; break; } catch {}
|
|
335
|
+
}
|
|
336
|
+
} catch {}
|
|
337
|
+
}
|
|
333
338
|
|
|
339
|
+
if (!uploaded) throw new Error(`Upload failed: ${filePath}`);
|
|
334
340
|
if (step.waitMs) await page.waitForTimeout(step.waitMs);
|
|
335
341
|
break;
|
|
336
342
|
}
|