107 lines
4.6 KiB
Markdown
107 lines
4.6 KiB
Markdown
---
|
|
description: Procesează toate screenshot-urile din screenshots/inbox/ paralel (5 agenți). Append serial cu partial-failure semantics.
|
|
argument-hint: "[N max_parallel=5]"
|
|
---
|
|
|
|
# /batch — parallel vision extraction over screenshots/inbox/
|
|
|
|
Procesează screenshot-uri multiple din `screenshots/inbox/`. Lansează până la **5 subagenți `m2d-extractor` în paralel** (cap rigid — context window + rate limits). După ce toți revin, append-ezi rezultatele **serial** (`append_row` citește/scrie CSV — paralelism la write = ID collision garantat).
|
|
|
|
## Workflow
|
|
|
|
### Fază 1 — Colectează lista
|
|
|
|
1. Listează `screenshots/inbox/*.png` (sortat alfabetic).
|
|
2. Dacă lista e goală → afișează `Inbox gol. Adaugă PNG-uri în screenshots/inbox/.` și oprește.
|
|
3. Dacă `$ARGUMENTS` conține un număr `N`, folosește-l ca `max_parallel` în loc de 5 (dar nu depăși niciodată 5 — hard cap).
|
|
|
|
### Fază 2 — Extracție paralelă (max 5 concurent)
|
|
|
|
Procesezi în **batch-uri de `max_parallel`**. Pentru fiecare batch:
|
|
|
|
- Lansezi câte un Task tool call cu `subagent_type: "m2d-extractor"` pentru fiecare screenshot, ÎN ACELAȘI MESAJ (tool calls paralele). Prompt per agent:
|
|
|
|
```
|
|
Extrage trade din `<absolute_path>`. Scrie JSON la `data/extractions/<basename_no_ext>.json` și log la `data/extractions/<basename_no_ext>.log`.
|
|
|
|
screenshot_path: <absolute_path>
|
|
screenshot_file: <basename>
|
|
```
|
|
|
|
- Aștepți să se întoarcă toți. Treci la următorul batch.
|
|
|
|
**De ce max 5**: peste 5 sub-agenți paraleli începi să saturezi context window-ul orchestratorului cu output-urile lor și rate limits-urile API-ului. Cap rigid.
|
|
|
|
### Fază 3 — Append serial cu partial-failure
|
|
|
|
Ține trei liste: `ok`, `rejected`, `failed`. Pentru fiecare PNG din lista originală, **în ordine alfabetică**:
|
|
|
|
1. **Verifică existența JSON-ului** `data/extractions/<basename_no_ext>.json`:
|
|
- Lipsește sau e corupt → mută PNG la `screenshots/needs_review/<basename>`, adaugă la `failed` cu motiv `missing/invalid JSON`, continuă.
|
|
|
|
2. **Apelează append** (source = `vision` — `/batch` nu suportă calibration, pentru asta folosește `/backtest --calibration` individual):
|
|
|
|
```bash
|
|
python -c "from pathlib import Path; from scripts.append_row import append_extraction; import json; r = append_extraction(Path('data/extractions/<basename_no_ext>.json'), source='vision'); print(json.dumps(r, default=str))"
|
|
```
|
|
|
|
3. **Reacționezi**:
|
|
- `status == "ok"` → mută PNG la `screenshots/processed/<basename>`, adaugă la `ok` cu `id`, `set`, `outcome_path`.
|
|
- `status == "rejected"` → mută PNG la `screenshots/needs_review/<basename>`, mută JSON la `data/extractions/rejected/<basename_no_ext>.json` (creează folderul dacă lipsește), adaugă la `rejected` cu `reason`.
|
|
|
|
4. **NU oprești batch-ul la primul fail**. Continuă până la capăt.
|
|
|
|
### Fază 4 — Regenerează MD o singură dată
|
|
|
|
```bash
|
|
python -m scripts.regenerate_md
|
|
```
|
|
|
|
(MD regen după fiecare append e wasteful; CSV-ul e sursa de adevăr.)
|
|
|
|
### Fază 5 — Scrie summary la `data/extractions/_batch_<utc_timestamp>.md`
|
|
|
|
`<utc_timestamp>` format ISO compact (ex: `2026-05-13T15-45-21Z`). Conținut:
|
|
|
|
```markdown
|
|
# Batch run <iso_utc_timestamp>
|
|
|
|
Total: <N> | OK: <n_ok> | REJECTED: <n_rej> | FAILED: <n_fail>
|
|
|
|
## OK
|
|
- <basename>.png → id=<id>, set=<set>, outcome_path=<outcome_path>
|
|
- ...
|
|
|
|
## REJECTED
|
|
- <basename>.png — reason: <reason>
|
|
- ...
|
|
|
|
## FAILED
|
|
- <basename>.png — <motiv: missing/invalid JSON>
|
|
- ...
|
|
```
|
|
|
|
Secțiuni goale se omit (dacă REJECTED e gol, nu scrii secțiunea).
|
|
|
|
### Fază 6 — Afișează summary user-ului
|
|
|
|
Format scurt în terminal:
|
|
|
|
```
|
|
/batch terminat. Total <N> screenshot-uri.
|
|
OK: <n_ok> (trade-uri #<id1>, #<id2>, ...)
|
|
REJECTED: <n_rej> (mutate la screenshots/needs_review/)
|
|
FAILED: <n_fail> (mutate la screenshots/needs_review/, JSON lipsă)
|
|
Regenerat data/jurnal.md.
|
|
Summary scris la data/extractions/_batch_<utc_timestamp>.md.
|
|
```
|
|
|
|
## Reguli
|
|
|
|
- **Hard cap concurrency la 5**. Chiar dacă `max_parallel` argumentat e mai mare, clamp la 5.
|
|
- **Append serial obligatoriu**. `append_extraction` citește CSV, computează `next_id`, scrie atomic; rulat paralel = ID-uri duplicate sau pierderi.
|
|
- **Partial failure = continuă**. Un screenshot prost nu blochează restul batch-ului.
|
|
- **MD regen o singură dată** la final.
|
|
- **Path discipline pentru subagent neschimbată**: agentul scrie doar la `data/extractions/`. Tu (orchestrator) muți screenshot-uri și rejected JSON-uri.
|
|
- `/batch` folosește mereu `source=vision`. Pentru calibration, rulează `/backtest --calibration` individual pe fiecare screenshot.
|