diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..63dc99d --- /dev/null +++ b/TODO.md @@ -0,0 +1,107 @@ +# TODO + +## Custom game prompt + +- Keep the default prompt (`prompt.txt`) as the base for every game. +- Add an optional **per-game custom prompt** in the UI that merges with the default (custom rules layered on top of shared instructions, not a full replacement unless explicitly chosen). +- Surface this in settings / project setup so each game folder can carry its own tone, terminology notes, or content warnings without forking the global prompt. + +## Batch history tab + +- Add a **Batch** tab (or dedicated panel) in the GUI to manage past Anthropic batch runs saved locally. +- Persist batch metadata locally (batch id, submit time, file set, status, cost estimate, etc.) alongside existing `log/batch_*.json` artifacts (`batch_state.json`, `batch_results.json`, `batch_requests.json`). +- Actions: + - **List batches** — browse all batches the tool has submitted or tracked for this project. + - **Redownload** — fetch results again from Anthropic for a completed batch (e.g. after a crash before consume, or to recover results). **Not in sketch yet.** + - **Cancel batch** — cancel an in-flight batch where the API allows it (`in_progress` → `canceling` → `ended`). + - **Usage / cost** — sum real billed tokens from batch results (input, output, cache read/write, thinking). + - Resume / link into the existing collect → submit → consume flow when a batch is still pending or fetched but not consumed. + +### Sketch: CLI batch manager (adapt for DazedMTLTool) + +Reference from sibling tooling (`batches.py`). Port to this repo using `_get_anthropic_client()` / `fetchTranslationBatches()` in `util/translation.py` and `log/batch_state.json` (maps to sketch's `tl/_batch_state.json`). + +```python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +batches.py — list and cancel Anthropic Message Batches (the ones DazedMTLTool +submits). Handy when a run is stuck polling or you submitted by mistake. + + set ANTHROPIC_API_KEY=sk-... # or key= in .env + + python tooling/batches.py # list recent batches (default) + python tooling/batches.py list --limit 50 + python tooling/batches.py cancel [ ...] + python tooling/batches.py cancel --all # cancel every in-progress batch + python tooling/batches.py cancel --mine # cancel batch(es) in log/batch_state.json + python tooling/batches.py usage [batch_id] # real billed tokens + estimated cost + + # TODO: redownload — re-fetch results into log/batch_results.json + +Only an in-progress batch can be cancelled; cancellation finishes any in-flight +requests (in_progress -> canceling -> ended). Already-ended batches can't be +cancelled. +""" +import os +import sys +import argparse +import collections + +# Adapt imports to DazedMTLTool: +# from util.translation import _get_anthropic_client, BATCH_STATE_FILE, _read_batch_file, fetchTranslationBatches + +CANCELABLE = {"in_progress"} + + +def _counts(b): + rc = getattr(b, "request_counts", None) + if not rc: + return "" + parts = [] + for k in ("processing", "succeeded", "errored", "canceled", "expired"): + v = getattr(rc, k, None) + if v: + parts.append(f"{k[:4]}={v}") + return " ".join(parts) + + +def _mine_batch_ids(): + """Return batch ids from log/batch_state.json (DazedMTLTool format).""" + # state = _read_batch_file(BATCH_STATE_FILE) or {} + # return [b["id"] for b in state.get("batches", [])] + ... + + +def cmd_list(client, limit): + mine = set(_mine_batch_ids()) + print(f"{'BATCH ID':<28} {'STATUS':<12} {'CREATED':<22} COUNTS") + print("-" * 90) + n = 0 + for b in client.messages.batches.list(limit=limit): + n += 1 + mark = " <- yours" if b.id in mine else "" + created = str(getattr(b, "created_at", "") or "")[:22] + print(f"{b.id:<28} {b.processing_status:<12} {created:<22} {_counts(b)}{mark}") + ... + + +def cmd_cancel(client, ids, do_all, do_mine, limit): + # targets from ids, --mine (log/batch_state.json), or --all (in_progress only) + # client.messages.batches.cancel(bid) + ... + + +def cmd_usage(client, bid, model): + # Sum usage across client.messages.batches.results(bid) + # Price with getPricingConfig(model) + 50% batch discount on I/O + ... + + +# cmd_redownload(client, bid): +# # TODO: client.messages.batches.results(bid) -> merge into log/batch_results.json +# # Wire custom_id map from batch_state.json entries +# ... +``` + +**GUI tab (later):** same operations as buttons on a saved local history table — list, cancel, usage, redownload, resume consume.