Spaces:
Sleeping
Sleeping
File size: 5,869 Bytes
7d46a91 1c9c13f 7d46a91 1c9c13f 7d46a91 1c9c13f 7d46a91 1c9c13f 7d46a91 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | # λ°λͺ¨ API κ³μ½ β μΉ λ¦¬λ β μμ§ (M6)
> μμΉ: **μ¨μ μν(trust/doubt/μ μ½λ)λ μ΄λ€ μλ΅μλ μ£μ§ μλλ€** (보μ΄μ§ μλ κ²μ).
> μΈμ
μμν: μμ¬ μμΉ + μ¨μ μνλ SQLite(`data/sessions.db`)μ λ§€ λ³κ²½ μ¦μ μ μ₯.
> μλ² μ¬μμ νμλ `GET /api/session/{sid}`λ‘ λ³΅μλλ€. **ν¬μΌ(μ±ν
) μ€κ° μνλ λΉμμ** β
> 볡μ μ ν¬μΌμ λ«ν μνλ‘ μμνκ³ , μ§ν μ€μ΄λ λνμ μ λ’°μΆ μ¦λΆμ μ μ€λλ€ (μΉμΈλ νΈλ μ΄λμ€ν).
> λ¨μΌ νλ‘μΈμ€ μ μ (μΈλ©λͺ¨λ¦¬ μΊμ + ADK μΈλ©λͺ¨λ¦¬ μΈμ
)λ μ μ§.
## κ³΅ν΅ νμ
```jsonc
// Step β λ¦¬λ© νλ©΄ ν μ₯
{
"card": {"id": "E01-01", "title": "μ΄λ μΌλ‘μ μ΄λ", "episode": "E01",
"episode_title": "μ 1ν: μ΄λ¦° λ°€μ μλ"},
"narration": [
{"type": "prose|dialogue_center|character_dialogue|stage_direction",
"text": "...", "speaker": "", // speakerλ character_dialogueλ§
"role": "lead_in|aftermath|null", // νλ©΄ λ°°μΉ μν β lead_in(λ°ν μ§μ μ§§μ λμ
)μ
// μ€ν
μ΄μ§ νλ©΄ μλ¨μ μΉνλ€ (μ λ: μ μ¬ μ κ·μΉ)
"portrait": "/assets/μΈλ¬Ό/μΉ΄λ₯΄λ°λΌ.png"} // νμ μ΄μ (router SPEAKER_PORTRAIT,
], // μμΌλ©΄ null β μ΄λ¦νλ§. μ μ Β·λ‘λΌλ νλ‘ νΈκ°
// 1μΈμΉ(μ€λ₯Έμͺ½ μ λ ¬)μΌλ‘ μ²λ¦¬
"choices": [{"label": "λμ λ¬λ€"}], // μμΌλ©΄ []
"can_chat": true, // κ°μ
ν¬μΌ(μμ μ±ν
) κ°λ₯ νμ΄μ§
"image": "/assets/νλμ΄ μ΄λ―Έμ§/4.png", // μ°μΆ μ»· (μμΌλ©΄ null). λ§€ν: router IMAGE_MAP
"background": "/assets/λ°°κ²½/μΉ¨μ€.png", // μ₯μ λ°°κ²½ (μΉ΄λ #μ₯μ/ νκ·Έ β router BACKGROUND_MAP,
// λ§€ν μλ μ₯μλ μ§μ λ°°κ²½ μ μ§ Β· μλ©μ null)
"progress": {"index": 5, "total": 44}, // μ½κΈ° μ§νλ (νμ΄μ§ λ¨μ)
// νμ΄μ§ = μ¬λ¬ μΉ΄λ λ³ν©(services/paging.py, κ²°μ μ
// νν°μ
Β· runλ³ κ· ν λΆν , λͺ©ν chapter.page_target_chars
// κΈ°λ³Έ 500μ). card.titleμ μ°Έκ³ μ© β ν΄λΌμ΄μΈνΈλ μΉ΄λ
// μμ λͺ©μ νμνμ§ μλλ€(μνΌμλ ν€λΒ·μ»· μΊ‘μ
λ§).
// card.id = νμ΄μ§ λ μΉ΄λ(μ νΒ·μ±ν
κΈ°μ€),
// title/episode = 첫 μΉ΄λ κΈ°μ€.
// μ°μΆ μ»·μ λ¨λ
νμ΄μ§ + νμ 2νμ΄μ§(μ»·+λ³Έλ¬Έ) β
// imageκ° μμΌλ©΄ μ»· νμ΄μ§ λ²νΈ = index - 1
// (ν΄λΌμ΄μΈνΈλ μ»·μ λ¨Όμ λ λν λ€ λ³Έλ¬Έ)
"ending": null // μ±ν° μ’
λ£ μμλ§ μλ Ending
}
// Ending
{"id": "ending_eternal", "label": "The Eternal β λν/μμ", "description": "..."}
// PocketTurn
{"reply": "β¦μ΄μν λ§μ νλꡬλ, λ‘λΌ.", "converged": false, "reason": null, "turn_no": 1}
```
## μλν¬μΈνΈ
| λ©μλ/κ²½λ‘ | μμ² | μλ΅ | λΉκ³ |
|---|---|---|---|
| `POST /api/session` | `{}` | `{"session_id", "step": Step}` | μ νλ μ΄ μμ (E01-01) |
| `GET /api/session/{sid}` | β | `{"step": Step}` | νμ¬ μμΉ μ¬μ‘°ν = **볡μ μ§μ
μ ** (μλ‘κ³ μΉ¨Β·μλ² μ¬μμ). 404λ©΄ μ μΈμ
μ λ§λ€ κ² |
| `POST /api/session/{sid}/advance` | `{}` | `{"step": Step}` | μ νμ§ μλ μΉ΄λμμ λ€μ μ₯ |
| `POST /api/session/{sid}/choose` | `{"index": 0}` | `{"picked": {"label","result"}, "step": Step}` | μ ν λ°μ(μΆμ μλ² λ΄λΆ) |
| `POST /api/session/{sid}/pocket/open` | `{}` | `{"opened": true}` | νμ¬ μΉ΄λμμ μ±ν
μμ. can_chat=falseλ©΄ 409 |
| `POST /api/session/{sid}/pocket/turn` | `{"text": "..."}` | `PocketTurn` | converged=trueλ©΄ μλ close(컀λ°) μλ£ μν |
| `POST /api/session/{sid}/pocket/close` | `{}` | `{"closed": true}` | μ μ κ° λ¨Όμ λνλ₯Ό μ μ λ (μ»€λ° ν¬ν¨) |
| `GET /api/meta` | β | `{"cover_image","title","subtitle","intro_images"}` | νμ§Β·μΈνΈλ‘ μνμ€(μν/μΈλ¬Ό μκ°Β·1μ₯ μμ β μ μμμλ§ νμ, μ΄μ΄ μ½κΈ°λ 건λλ) |
| `GET /assets/β¦` | β | μ΄λ―Έμ§ νμΌ | μ°μΆ μμ
(λνλ μ°μΆλ¬Ό, μ½κΈ° μ μ©) |
μ€λ₯: μ‘΄μ¬νμ§ μλ μΈμ
**λλ μ½ν
μΈ κ°±μ μΌλ‘ 무ν¨νλ μΈμ
** 404 Β·
μνμ μ λ§λ νΈμΆ(μ νμ§ μΉ΄λμμ advance λ±) 409 Β· `{"detail": "..."}` (FastAPI κΈ°λ³Έ ν¬λ§·).
- ν΄λΌμ΄μΈνΈλ `session_id`λ₯Ό `localStorage`(`carmilla_sid`)μ 보κ΄νκ³ , κΈ°λ μ GETμΌλ‘ 볡μμ
μλνλ€. 404λ©΄ ν€λ₯Ό λ²λ¦¬κ³ μ μΈμ
. 볡μ λ²μλ "νμ¬ νμ΄μ§λΆν°" β λ€λ‘κ°κΈ° νμ€ν 리λ μΈμ
λ΄ νμ
- μ½ν
μΈ (λΉνΈμΉ΄λ) μ¬λ³νμΌλ‘ μΉ΄λ ID/μμκ° λ°λλ©΄ κΈ°μ‘΄ μΈμ
μ μλ²κ° 무ν¨ννλ€ (λ²μ μ€ν¬ν)
## νλ¦
```
POST /api/session ββ step
ββ choices=[] ββββ POST advance βββ step (λ°λ³΅)
ββ choices=[...] β POST choose βββ picked.result νμ β step
β ββ (μ ν μ ) POST pocket/open β pocket/turn* β converged β μ νμ§λ‘ 볡κ·
ββ ending βββββββ μλ© νλ©΄
```
- ν¬μΌ μλ ΄/ν΄ μν(6ν΄)Β·μ΅μ 체λ₯(2ν΄)λ μλ² μ½λκ° κ°μ . ν΄λΌμ΄μΈνΈλ convergedλ§ λ°λ₯Έλ€
- ν΄ λ‘κ·Έλ μλ²κ° `logs/playlog.jsonl`μ κΈ°λ‘ (μ°κ΅¬ λ°μ΄ν°)
|