// SFT uçtan uca: app'in GERÇEK workflow kodu → ComfyUI → mp3. // Çalıştırma: dart run tool/e2e_sft.dart import 'dart:convert'; import 'dart:io'; import '../lib/comfy/workflow/muzik_workflow.dart'; Future main() async { const base = 'http://127.0.0.1:8188'; final http = HttpClient(); // App'in kendi parametre nesnesi — SFT bileşen modeli. final p = MuzikParametreleri( model: 'acestep_v1.5_xl_sft_bf16.safetensors', tags: 'warm neo-soul, rhodes piano, female vocals, 90 bpm', lyrics: '[verse]\nsft works now\n[chorus]\nhook line', seed: 0, bpm: 90, sureSn: 12, dil: 'en', steps: 14, cfg: 7.0, cfgScale: 2.0, ); final workflow = muzikWorkflowOlustur(p); stdout.writeln('aioMu: ${p.aioMu}'); stdout.writeln('node 105 (DualCLIP): ${workflow['105']?['class_type']}'); Future> post(String yol, Map govde) async { final istek = await http.postUrl(Uri.parse('$base$yol')); istek.headers.contentType = ContentType.json; istek.write(jsonEncode(govde)); final cevap = await istek.close(); return jsonDecode(await cevap.transform(utf8.decoder).join()) as Map; } Future> get(String yol) async { final istek = await http.getUrl(Uri.parse('$base$yol')); final cevap = await istek.close(); return jsonDecode(await cevap.transform(utf8.decoder).join()) as Map; } final sonuc = await post('/prompt', {'prompt': workflow, 'client_id': 'fikoyt-e2esft'}); if (sonuc['error'] != null) { stdout.writeln('RED: ${jsonEncode(sonuc['error'])}'); exit(1); } final pid = sonuc['prompt_id'] as String; stdout.writeln('prompt_id: $pid bekleniyor...'); for (var i = 0; i < 120; i++) { await Future.delayed(const Duration(seconds: 4)); final hist = await get('/history/$pid'); final kayit = hist[pid] as Map?; if (kayit == null) continue; final st = kayit['status'] as Map?; if (st?['status_str'] == 'error') { stdout.writeln('HATA: ${jsonEncode(st)}'); exit(1); } if (st?['completed'] == true) { final outs = kayit['outputs'] as Map; stdout.writeln('BASARILI: ${jsonEncode(outs)}'); exit(0); } } stdout.writeln('ZAMAN ASIMI'); exit(1); }