Spaces:
Sleeping
Sleeping
| # λ°λͺ¨ 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`μ κΈ°λ‘ (μ°κ΅¬ λ°μ΄ν°) | |