WillHbx commited on
Commit
e3725c4
·
1 Parent(s): 2adf2c5

docs: Update documentation

Browse files
Files changed (3) hide show
  1. CLAUDE.md +6 -0
  2. docs/ARCHITECTURE.md +2 -2
  3. 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": "neutral|joy|fear|anger|sad|surprise|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,7 +166,7 @@ class GameState(BaseModel):
166
  }
167
  ```
168
 
169
- `emotion` is required and constrained to an enum (cheap mood→sprite mapping). Every nested object is optional/nullable so simple turns stay tiny. **All of this is grammar-enforced** `complete_json` cannot return anything that doesn’t parse.
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 ::= "\"neutral\"" | "\"joy\"" | "\"fear\"" | "\"anger\"" | "\"sad\"" | "\"surprise\"" | "\"tender\""
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. Keep `max_tokens` tight (≈512) for the director call — it should be short.
 
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.