Cleaning things up
This commit is contained in:
parent
92a336d32d
commit
b91d5b9acd
10 changed files with 81 additions and 58 deletions
|
|
@ -177,7 +177,12 @@ Format: Japanese name, English name in parentheses, then gender.
|
|||
> **Note:** A very large vocab file can increase API costs and potentially reduce quality. Focus on the most important characters and terms.
|
||||
|
||||
### data/skills/system.md
|
||||
This is the system prompt skill sent to the AI on every translation call. A default `data/skills/system.md` is included and works well for most games. You generally don't need to edit it unless you want to customize the translation style. Per-game voice rules go in `<game>/skills/quirks.md` instead.
|
||||
This is the system prompt skill sent to the AI on every translation call. A default `data/skills/system.md` is included and works well for most games. You generally don't need to edit it unless you want to customize the translation style.
|
||||
|
||||
Per-game overlays (when a game folder is selected in Workflow) live next to the game:
|
||||
- `<game>/skills/game.md` - Translation Frame (theme / era / register / naming)
|
||||
- `<game>/skills/quirks.md` - cross-cutting voice habits
|
||||
- optional extra `<game>/skills/*.md` custom overlays
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ Regenerate mode: if the user asks for only one block (`glossary`, `speakers`, `t
|
|||
| `glossary` | Named characters (gender, role, **per-character** speech register) + worldbuilding terms | Global dialect / person rules; honorific policy; speaker-format flags; formatting |
|
||||
| `speakers` | Tool flag ENABLE/SKIP + short evidence | Character bios; quirks; full glossary |
|
||||
| `translation_quirks` | Cross-cutting voice rules (battle-log person, global dialect, item-description style, **unusual** honorific habits) | Per-character register; "always keep -san" (tool base prompt already does); codes/wrap/line counts; speaker flags |
|
||||
| `game_skill` | **Translation Frame** (theme / era / register / naming / optional myth), pointer to `skills/quirks.md`, tool boundaries | File inventories; verbatim quirks; verbatim glossary; per-character register; restating base honorific/formatting policy |
|
||||
| `game_skill` | **Translation Frame** for the API (theme / era / register / naming / optional myth) saved at `skills/game.md` | File inventories; quirks bullets; glossary; per-character register; IDE scaffolding; restating base honorific/formatting policy |
|
||||
|
||||
Hard rules:
|
||||
1. Per-character voice → `glossary` only.
|
||||
2. Category-wide / cross-cutting voice → `translation_quirks` only.
|
||||
3. Default honorifics policy is owned by the tool base prompt - only note **unusual** honorific habits in quirks.
|
||||
4. `game_skill` **references** `skills/quirks.md` only; do not reprint those rules or cite legacy names like `translation_quirks.txt`.
|
||||
4. `game_skill` is the title's Translation Frame for the translation API - keep it compact; do not reprint quirks or glossary.
|
||||
5. `speakers` is config, not lore.
|
||||
|
||||
---
|
||||
|
|
@ -98,25 +98,26 @@ Output as short imperative bullets suitable to paste into `skills/quirks.md`.
|
|||
|
||||
### Game skill rules (for `game_skill` block)
|
||||
|
||||
Produce a durable IDE skill for this title saved at `skills/translation.md`.
|
||||
Produce the per-game translation skill saved at `skills/game.md`.
|
||||
DazedMTLTool **merges this file into the translation system prompt** (before quirks).
|
||||
|
||||
**Translation Frame** (required section - one compact line per field; evidence-based only):
|
||||
**Translation Frame only** (one compact line per field; evidence-based):
|
||||
- `世界観 (Theme / setting)` - genre, world type, core atmosphere
|
||||
- `時代感 (Era / technology level)` - medieval / modern / sci-fi / historical / etc.
|
||||
- `文体方針 (Register policy)` - overall English style (plain RPG, mythic, courtly, modern casual, military, gothic, …)
|
||||
- `固有名詞方針 (Naming policy)` - invented names, titles, ranks, honorifics, myth-derived terms (high-level only; default honorific keep-policy stays in the tool base prompt)
|
||||
- `神話・伝承 (Myth / folklore basis)` - **omit unless** evidence supports a specific tradition or source family
|
||||
|
||||
Also include:
|
||||
- **Voice rules** - pointer only to ``skills/quirks.md`` (authoritative)
|
||||
- **Tool boundaries** - codes/formatting owned by the tool; do not reprint quirks or glossary
|
||||
- Do **not** list repo files / "files that matter"
|
||||
- Do **not** put per-character register here (glossary) or battle-log / dialect bullets here (quirks)
|
||||
Do **not** include:
|
||||
- Voice-rules pointers, tool-boundary essays, or IDE instructions
|
||||
- Repo file inventories / "files that matter"
|
||||
- Per-character register (glossary) or battle-log / dialect bullets (quirks)
|
||||
- Verbatim quirks or glossary entries
|
||||
|
||||
**Path names (required):**
|
||||
- Voice quirks file: ``skills/quirks.md`` (never ``translation_quirks.txt`` or any other legacy name)
|
||||
- This IDE skill file: ``skills/translation.md``
|
||||
- Optional user overlays (if mentioned): other ``skills/*.md`` files except ``quirks.md`` / ``translation.md``
|
||||
**Paths:**
|
||||
- Game skill (API): ``skills/game.md``
|
||||
- Quirks (API): ``skills/quirks.md`` (never ``translation_quirks.txt``)
|
||||
- Optional custom API overlays: other ``skills/*.md`` except those two
|
||||
|
||||
<!-- /engine:rpgmaker -->
|
||||
|
||||
|
|
@ -173,12 +174,10 @@ Label the fence language as `translation_quirks`. Inside: imperative bullet list
|
|||
|
||||
### Block `game_skill`
|
||||
|
||||
Label the fence language as `game_skill`. Inside: full markdown for `skills/translation.md`.
|
||||
|
||||
Required skeleton (fill in the blanks; keep the Voice rules path exactly):
|
||||
Label the fence language as `game_skill`. Inside: markdown for `skills/game.md` (Translation Frame only).
|
||||
|
||||
```markdown
|
||||
# <Game title> - Translation skill
|
||||
# <Game title> - Translation Frame
|
||||
|
||||
## Translation Frame
|
||||
世界観 (Theme / setting) - <one compact line>
|
||||
|
|
@ -186,15 +185,6 @@ Required skeleton (fill in the blanks; keep the Voice rules path exactly):
|
|||
文体方針 (Register policy) - <one compact line>
|
||||
固有名詞方針 (Naming policy) - <one compact line>
|
||||
神話・伝承 (Myth / folklore basis) - <one compact line, or omit this line entirely if unsupported>
|
||||
|
||||
## Voice rules
|
||||
Follow `skills/quirks.md` as the authoritative cross-cutting voice guide for this title.
|
||||
Do not invent alternate quirk filenames.
|
||||
|
||||
## Tool boundaries
|
||||
- DazedMTLTool owns formatting codes, wrap, line counts, and honorifics defaults via its base system skill.
|
||||
- Per-character register lives in the glossary (`vocab.txt`), not here.
|
||||
- Do not reprint quirks or glossary entries in this file.
|
||||
```
|
||||
|
||||
If known speakers were prepended in a `<known_speakers>` block above this skill, prefer those names in the glossary, then cross-check Actors.json for other major named actors.
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ class SkillsTab(QWidget):
|
|||
|
||||
intro = QLabel(
|
||||
"Tool-level AI instructions live here. "
|
||||
"Per-game quirks, the game IDE skill, and optional custom skills are edited "
|
||||
"in Workflow Step 2 (they travel with the game folder)."
|
||||
"Per-game quirks, Translation Frame (game skill), and optional custom skills are edited "
|
||||
"in Workflow Step 2 (they travel with the game folder and merge into the API prompt)."
|
||||
)
|
||||
intro.setWordWrap(True)
|
||||
intro.setStyleSheet(_HINT_STYLE)
|
||||
|
|
|
|||
|
|
@ -3018,7 +3018,7 @@ class TranslationTab(QWidget):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
# Per-game quirks overlay: Workflow Step 0 folder → DAZED_GAME_ROOT
|
||||
# Per-game overlays (game.md / quirks / custom): Workflow folder → DAZED_GAME_ROOT
|
||||
try:
|
||||
game_root = ""
|
||||
if self.settings:
|
||||
|
|
|
|||
|
|
@ -445,10 +445,10 @@ _STEP_HELP: dict[int, str] = {
|
|||
"• <code>translation_quirks</code> → Quirks tab "
|
||||
"(<code>skills/quirks.md</code>)<br>"
|
||||
"• <code>game_skill</code> → Game skills → translation tab "
|
||||
"(<code>skills/translation.md</code>)<br><br>"
|
||||
"(<code>skills/game.md</code> - Translation Frame, merged into the API prompt)<br><br>"
|
||||
"Optional: <b>+</b> on Game skills adds custom <code>skills/*.md</code> "
|
||||
"overlays (merged into the API prompt - can hurt quality; use sparingly).<br><br>"
|
||||
"Use one game folder per translation run so quirks stay in the prompt cache."
|
||||
"overlays (also merged into the API prompt - can hurt quality; use sparingly).<br><br>"
|
||||
"Use one game folder per translation run so frame/quirks stay in the prompt cache."
|
||||
),
|
||||
3: (
|
||||
"<b>Step 3 - TL Phase 1</b><br><br>"
|
||||
|
|
@ -1793,7 +1793,7 @@ class WorkflowTab(QWidget):
|
|||
"Quirks",
|
||||
)
|
||||
|
||||
# Game skills: built-in translation.md + optional custom overlays
|
||||
# Game skills: built-in game.md + optional custom overlays
|
||||
game_skills_page = QWidget()
|
||||
gs_layout = QVBoxLayout(game_skills_page)
|
||||
gs_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
|
@ -1845,11 +1845,11 @@ class WorkflowTab(QWidget):
|
|||
gs_layout.addWidget(self._game_skills_stack, 1)
|
||||
|
||||
self._add_game_skill_page(
|
||||
"translation",
|
||||
"game",
|
||||
_editor_page(
|
||||
"<game>/skills/translation.md",
|
||||
"Paste the game_skill block (Translation Frame + voice/tool pointers). "
|
||||
"IDE companion skill for this game repo (not injected into the API prompt).",
|
||||
"<game>/skills/game.md",
|
||||
"Paste the game_skill Translation Frame. Merged into the translation "
|
||||
"system prompt (before quirks) when this game folder is selected.",
|
||||
self._save_game_skill,
|
||||
self._reload_game_skill,
|
||||
"game_skill_editor",
|
||||
|
|
@ -2437,7 +2437,7 @@ class WorkflowTab(QWidget):
|
|||
# Pre-populate all Phase 2 checkboxes from current module state
|
||||
self._populate_p2_checkboxes()
|
||||
|
||||
# ── Step 5: Plugins/scripts + Export ───────────────────────────────────
|
||||
# ── Step 5: Plugins.js + Export ────────────────────────────────────────
|
||||
|
||||
def _build_step5_finish(self, layout: QVBoxLayout):
|
||||
self._add_step_header(layout, "Step 5 — Plugins & Export", 5)
|
||||
|
|
@ -3692,7 +3692,7 @@ class WorkflowTab(QWidget):
|
|||
if bar is None or stack is None:
|
||||
return
|
||||
|
||||
# Remove existing custom tabs (index 0 is always translation).
|
||||
# Remove existing custom tabs (index 0 is always game.md).
|
||||
while bar.count() > 1:
|
||||
bar.removeTab(1)
|
||||
while stack.count() > 1:
|
||||
|
|
@ -3757,8 +3757,8 @@ class WorkflowTab(QWidget):
|
|||
"<b>Custom skills are merged into the translation system prompt.</b><br><br>"
|
||||
"Extra or poorly written skills can <b>distract the model and hurt "
|
||||
"translation quality</b> (conflicting rules, prompt bloat, diluted quirks).<br><br>"
|
||||
"Prefer <code>quirks.md</code> for voice rules and <code>translation.md</code> "
|
||||
"for IDE guidance. Add a custom skill only if you need a rare, tightly scoped "
|
||||
"Prefer <code>quirks.md</code> for voice rules and <code>game.md</code> "
|
||||
"for the Translation Frame. Add a custom skill only if you need a rare, tightly scoped "
|
||||
"overlay - <b>at your own risk</b>."
|
||||
)
|
||||
warn.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok)
|
||||
|
|
@ -3783,7 +3783,7 @@ class WorkflowTab(QWidget):
|
|||
self,
|
||||
"Invalid name",
|
||||
"Use a short name like battle-log or honorifics_extra.\n"
|
||||
"Reserved: quirks, translation.",
|
||||
"Reserved: quirks, game, translation.",
|
||||
)
|
||||
return
|
||||
if stem in self._custom_skill_editors:
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ def handleMVMZ(filename, estimate):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
# Reload base prompt + optional per-game quirks (DAZED_GAME_ROOT).
|
||||
# Reload system.md + per-game overlays (game.md / quirks / custom) via DAZED_GAME_ROOT.
|
||||
PROMPT = load_system_prompt()
|
||||
TRANSLATION_CONFIG.prompt = PROMPT
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ def handleWolfDawn(filename, estimate):
|
|||
# that an earlier Phase 0 (names) harvested into vocab.txt.
|
||||
VOCAB = VOCAB_PATH.read_text(encoding="utf-8")
|
||||
TRANSLATION_CONFIG.vocab = VOCAB
|
||||
# Reload base prompt + optional per-game quirks (DAZED_GAME_ROOT).
|
||||
# Reload system.md + per-game overlays (game.md / quirks / custom) via DAZED_GAME_ROOT.
|
||||
PROMPT = load_system_prompt()
|
||||
TRANSLATION_CONFIG.prompt = PROMPT
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,10 @@ TRANSLATION_CONTEXTS_PATH = DATA_DIR / "translation_contexts.json"
|
|||
# Per-game quirks skill (API overlay). Legacy flat file still migrated on load.
|
||||
GAME_QUIRKS_RELATIVE = Path("skills") / "quirks.md"
|
||||
LEGACY_QUIRKS_FILENAME = "translation_quirks.txt"
|
||||
GAME_SKILL_RELATIVE = Path("skills") / "translation.md"
|
||||
GAME_SKILL_RELATIVE = Path("skills") / "game.md"
|
||||
LEGACY_GAME_SKILL_RELATIVE = Path("skills") / "translation.md"
|
||||
# Built-in skill filenames under <game>/skills/ (not user-custom overlays).
|
||||
GAME_SKILL_RESERVED_NAMES = frozenset({"quirks.md", "translation.md"})
|
||||
GAME_SKILL_RESERVED_NAMES = frozenset({"quirks.md", "game.md", "translation.md"})
|
||||
|
||||
_ROOT_DATA_FILES = (
|
||||
"vocab.txt",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
"""Load the static system prompt and optional per-game quirks overlay."""
|
||||
"""Load the static system prompt and optional per-game skill overlays."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -10,12 +10,19 @@ from util.paths import (
|
|||
GAME_QUIRKS_RELATIVE,
|
||||
GAME_SKILL_RELATIVE,
|
||||
GAME_SKILL_RESERVED_NAMES,
|
||||
LEGACY_GAME_SKILL_RELATIVE,
|
||||
LEGACY_QUIRKS_FILENAME,
|
||||
PROMPT_PATH,
|
||||
)
|
||||
|
||||
_SKILL_NAME_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$")
|
||||
|
||||
# Drop legacy IDE-only sections from older game skill files.
|
||||
_IDE_SECTION_RE = re.compile(
|
||||
r"\n## (?:Voice rules|Tool boundaries)\b.*?(?=\n## |\Z)",
|
||||
re.DOTALL | re.IGNORECASE,
|
||||
)
|
||||
|
||||
|
||||
def quirks_path_for_game(game_root: str | Path | None) -> Path | None:
|
||||
"""Return ``<game_root>/skills/quirks.md`` when *game_root* is set.
|
||||
|
|
@ -38,27 +45,40 @@ def quirks_path_for_game(game_root: str | Path | None) -> Path | None:
|
|||
|
||||
|
||||
def game_skill_path_for_game(game_root: str | Path | None) -> Path | None:
|
||||
"""Return ``<game_root>/skills/translation.md`` when *game_root* is set."""
|
||||
"""Return ``<game_root>/skills/game.md`` when *game_root* is set.
|
||||
|
||||
Migrates legacy ``skills/translation.md`` to ``skills/game.md`` when needed.
|
||||
"""
|
||||
if not game_root:
|
||||
return None
|
||||
return Path(game_root) / GAME_SKILL_RELATIVE
|
||||
root = Path(game_root)
|
||||
preferred = root / GAME_SKILL_RELATIVE
|
||||
legacy = root / LEGACY_GAME_SKILL_RELATIVE
|
||||
if not preferred.is_file() and legacy.is_file():
|
||||
preferred.parent.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
legacy.rename(preferred)
|
||||
except OSError:
|
||||
return legacy
|
||||
return preferred
|
||||
|
||||
|
||||
def migrate_game_skill_text(text: str) -> str:
|
||||
"""Rewrite legacy quirk path names inside a game skill markdown body."""
|
||||
"""Normalize a game skill body for API use (path fixes + drop IDE scaffolding)."""
|
||||
if not text:
|
||||
return text
|
||||
# Common stale pointers from older Project Setup output.
|
||||
updated = text.replace("translation_quirks.txt", "skills/quirks.md")
|
||||
updated = updated.replace("`translation_quirks.md`", "`skills/quirks.md`")
|
||||
# Bare relative quirks.md without skills/ prefix (keep skills/quirks.md intact).
|
||||
updated = re.sub(
|
||||
r"(?<!skills/)(?<![\w./-])quirks\.md(?![\w.-])",
|
||||
"skills/quirks.md",
|
||||
updated,
|
||||
)
|
||||
# Avoid double skills/skills/
|
||||
updated = updated.replace("skills/skills/quirks.md", "skills/quirks.md")
|
||||
# Older templates included IDE-only Voice rules / Tool boundaries sections.
|
||||
updated = _IDE_SECTION_RE.sub("\n", updated)
|
||||
updated = re.sub(r"\n{3,}", "\n\n", updated).strip() + "\n"
|
||||
return updated
|
||||
|
||||
|
||||
|
|
@ -98,7 +118,7 @@ def custom_skill_path_for_game(
|
|||
def list_custom_skill_paths(game_root: str | Path | None) -> list[Path]:
|
||||
"""List user custom skill markdown files under ``<game>/skills/``.
|
||||
|
||||
Excludes built-in ``quirks.md`` and ``translation.md``.
|
||||
Excludes built-in ``quirks.md`` and ``game.md`` (and legacy ``translation.md``).
|
||||
"""
|
||||
skills = game_skills_dir(game_root)
|
||||
if skills is None or not skills.is_dir():
|
||||
|
|
@ -116,9 +136,10 @@ def list_custom_skill_paths(game_root: str | Path | None) -> list[Path]:
|
|||
def load_system_prompt(game_root: str | Path | None = None) -> str:
|
||||
"""Load ``data/skills/system.md`` plus optional per-game overlays.
|
||||
|
||||
Overlay order:
|
||||
1. ``skills/quirks.md`` (voice quirks)
|
||||
2. Any other ``skills/*.md`` except ``translation.md`` (custom skills)
|
||||
Overlay order (when ``DAZED_GAME_ROOT`` / *game_root* is set):
|
||||
1. ``skills/game.md`` - Translation Frame / game skill (API)
|
||||
2. ``skills/quirks.md`` - cross-cutting voice quirks
|
||||
3. other ``skills/*.md`` - optional custom overlays
|
||||
|
||||
Path resolution order for the game root:
|
||||
1. Explicit *game_root* argument
|
||||
|
|
@ -135,6 +156,12 @@ def load_system_prompt(game_root: str | Path | None = None) -> str:
|
|||
|
||||
parts = [base.rstrip()] if base.strip() else []
|
||||
|
||||
skill_file = game_skill_path_for_game(root)
|
||||
if skill_file and skill_file.is_file():
|
||||
skill = migrate_game_skill_text(skill_file.read_text(encoding="utf-8")).strip()
|
||||
if skill:
|
||||
parts.append("## Game Translation Frame\n\n" + skill)
|
||||
|
||||
quirks_file = quirks_path_for_game(root)
|
||||
if quirks_file and quirks_file.is_file():
|
||||
quirks = quirks_file.read_text(encoding="utf-8").strip()
|
||||
|
|
|
|||
|
|
@ -1945,7 +1945,7 @@ def createContext(config, subbedText, formatType, history=None):
|
|||
cache invalidation caused by changing vocabulary matches.
|
||||
|
||||
Cached in static_system:
|
||||
- data/skills/system.md content (plus optional game quirks overlay)
|
||||
- data/skills/system.md content (plus optional game Translation Frame / quirks / custom overlays)
|
||||
|
||||
Dynamic in vocab_text:
|
||||
- only vocab terms found in the current batch text
|
||||
|
|
|
|||
Loading…
Reference in a new issue