docs: Update documentation
Browse files- CLAUDE.md +6 -0
- docs/ARCHITECTURE.md +2 -2
- docs/PROMPTS.md +3 -4
CLAUDE.md
CHANGED
|
@@ -117,6 +117,12 @@ engine._view ─▶ ViewState ─▶ frontend/index.html (backdrop + sprite + d
|
|
| 117 |
6. **Context window is finite** ("Thousand Token Wood"). Feed summary + present sheets + last k turns —
|
| 118 |
never the whole log. `memory.py` enforces it.
|
| 119 |
7. **Spaces filesystem is ephemeral.** `.md` memory is per-session unless you wire HF persistent storage.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
## Definition of done (MVP)
|
| 122 |
|
|
|
|
| 117 |
6. **Context window is finite** ("Thousand Token Wood"). Feed summary + present sheets + last k turns —
|
| 118 |
never the whole log. `memory.py` enforces it.
|
| 119 |
7. **Spaces filesystem is ephemeral.** `.md` memory is per-session unless you wire HF persistent storage.
|
| 120 |
+
8. **Qwen3 think-mode on ZeroGPU.** Qwen3-14B via `transformers` sometimes puts the entire JSON answer
|
| 121 |
+
inside its `<think>` block and emits nothing after `</think>`. `TransformersLLM.complete_json` handles
|
| 122 |
+
this by calling `apply_chat_template(..., enable_thinking=False)` to suppress thinking for structured
|
| 123 |
+
output, and falls back to searching inside the think block if no JSON appears after it. Do NOT use
|
| 124 |
+
`_quiet_stderr()` around transformers loads — it swallows loading errors that are essential for
|
| 125 |
+
ZeroGPU debugging.
|
| 126 |
|
| 127 |
## Definition of done (MVP)
|
| 128 |
|
docs/ARCHITECTURE.md
CHANGED
|
@@ -153,7 +153,7 @@ class GameState(BaseModel):
|
|
| 153 |
{
|
| 154 |
"speaker": "lantern_moth", // which present character speaks (or "narrator")
|
| 155 |
"dialogue": "string", // their line, in voice
|
| 156 |
-
"emotion": "
|
| 157 |
"directives": {
|
| 158 |
"scene_change": null, // or { "place": "...", "description": "...", "mood": "..." }
|
| 159 |
"new_character": null, // or a partial Character (id,name,one_line,appearance,voice,traits,goals)
|
|
@@ -166,7 +166,7 @@ class GameState(BaseModel):
|
|
| 166 |
}
|
| 167 |
```
|
| 168 |
|
| 169 |
-
`emotion` is
|
| 170 |
|
| 171 |
### 4.3 `.md` as a derived view (not the truth)
|
| 172 |
|
|
|
|
| 153 |
{
|
| 154 |
"speaker": "lantern_moth", // which present character speaks (or "narrator")
|
| 155 |
"dialogue": "string", // their line, in voice
|
| 156 |
+
"emotion": "string", // free-form mood word (e.g. "curious", "tender") → sprite mood
|
| 157 |
"directives": {
|
| 158 |
"scene_change": null, // or { "place": "...", "description": "...", "mood": "..." }
|
| 159 |
"new_character": null, // or a partial Character (id,name,one_line,appearance,voice,traits,goals)
|
|
|
|
| 166 |
}
|
| 167 |
```
|
| 168 |
|
| 169 |
+
`emotion` is a free-form string (the LLM picks whatever fits the moment). Every nested object is optional/nullable so simple turns stay tiny. `complete_json` enforces structure on the llama.cpp path via GBNF; on the `transformers` path it uses prompt-based JSON extraction with 3-attempt retry.
|
| 170 |
|
| 171 |
### 4.3 `.md` as a derived view (not the truth)
|
| 172 |
|
docs/PROMPTS.md
CHANGED
|
@@ -107,8 +107,7 @@ out = llm.create_chat_completion(
|
|
| 107 |
"properties": {
|
| 108 |
"speaker": { "type": "string" },
|
| 109 |
"dialogue": { "type": "string" },
|
| 110 |
-
"emotion": { "type": "string",
|
| 111 |
-
"enum": ["neutral","joy","fear","anger","sad","surprise","tender"] },
|
| 112 |
"directives": {
|
| 113 |
"type": "object",
|
| 114 |
"additionalProperties": false,
|
|
@@ -199,7 +198,7 @@ ending ::= "{" ws
|
|
| 199 |
"\"kind\"" ws ":" ws ("\"warm\"" | "\"bittersweet\"" | "\"strange\"") ws "," ws
|
| 200 |
"\"text\"" ws ":" ws string ws "}"
|
| 201 |
|
| 202 |
-
emotion ::=
|
| 203 |
|
| 204 |
flagobj ::= "{" ws ( flagpair ( ws "," ws flagpair )* ws )? "}"
|
| 205 |
flagpair ::= string ws ":" ws string
|
|
@@ -244,4 +243,4 @@ For **mood swaps** with FLUX.2 Klein, condition on the cached base sprite instea
|
|
| 244 |
| Memory compaction | 0.3 | 0.9 | want faithful, terse summary |
|
| 245 |
| Image-prompt | — | — | composed in code, no sampling |
|
| 246 |
|
| 247 |
-
Add a light `repeat_penalty` (~1.05–1.1) to fight the “AI slop” repetition small models drift into.
|
|
|
|
| 107 |
"properties": {
|
| 108 |
"speaker": { "type": "string" },
|
| 109 |
"dialogue": { "type": "string" },
|
| 110 |
+
"emotion": { "type": "string" },
|
|
|
|
| 111 |
"directives": {
|
| 112 |
"type": "object",
|
| 113 |
"additionalProperties": false,
|
|
|
|
| 198 |
"\"kind\"" ws ":" ws ("\"warm\"" | "\"bittersweet\"" | "\"strange\"") ws "," ws
|
| 199 |
"\"text\"" ws ":" ws string ws "}"
|
| 200 |
|
| 201 |
+
emotion ::= string
|
| 202 |
|
| 203 |
flagobj ::= "{" ws ( flagpair ( ws "," ws flagpair )* ws )? "}"
|
| 204 |
flagpair ::= string ws ":" ws string
|
|
|
|
| 243 |
| Memory compaction | 0.3 | 0.9 | want faithful, terse summary |
|
| 244 |
| Image-prompt | — | — | composed in code, no sampling |
|
| 245 |
|
| 246 |
+
Add a light `repeat_penalty` (~1.05–1.1) to fight the “AI slop” repetition small models drift into. Use `max_tokens≈1024` for the director call — actions like `scout` (which must fill a full `new_character` object) need the extra budget.
|