DazedTL/TODO.md
2026-07-05 15:06:23 -05:00

6.1 KiB

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_progresscancelingended).
    • 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).

#!/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 <batch_id> [<batch_id> ...]
    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 <batch_id>  — 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.

Local translation cache (game retranslate)

  • Persist every successful translation locally so a full retranslate from scratch can reuse prior results instead of paying again.
  • Cache key: hash the translation payload (source Japanese text sent to the model) plus target language — same approach as the existing global cache in util/translation.py (get_cache_key, log/translation_cache.json). Payload keys naturally dedupe identical lines across files and survive re-extract / re-import as long as the source string is unchanged.
  • Scope: consider a per-game cache file under the game project (e.g. <game_root>/translation_cache.json or alongside wolf_json/) in addition to (or merged with) the tool-wide log/translation_cache.json, so caches travel with the game folder and are easy to back up.
  • Write path: on every successful translate (live and batch consume), store {cache_key: translation} before or as results land in translated/.
  • Read path: before calling the API, check cache; on hit, skip the request and apply the cached translation (respecting file-specific re-expansion where the payload is Japanese-only).
  • Retranslate workflow: when the user re-imports fresh JSON and runs Translate again, cache hits should fill translated/ automatically for unchanged source lines; only new or edited source text should incur API cost.
  • UI (later): cache stats (hits / misses / estimated savings), export/import, clear cache for one game, optional “prefer cache” toggle.
  • Invalidation: optional metadata (model id, prompt version) in the key or entry if we need to avoid reusing stale translations after prompt or model changes.