Files
Project_Velocity/.Agent Context/Bibels/dreamweaver_ios_integration_guide.md

198 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dream Weaver API v2 — iOS Integration Guide (Dynamic Keywords)
**Version:** 2.0-FINAL | **Updated:** 2026-03-09 | **Server:** `54.172.172.2` | **Port:** `8082`
> This document is for **Sayan** (iOS / Swift).
> Dream Weaver API v2 introduces a **Dynamic Keyword to Local LLM Prompt Expansion** system.
> The app no longer relies on 5 hardcoded styles. Users can pick ANY keywords, and a local LLM (Qwen 3.5 27B via Ollama) will generate a photorealistic interior design prompt based on the room type without sending data to the cloud.
> [!CAUTION]
> **PORT 8080 IS DEAD.** Do not use port 8080 anymore. The old gateway process has been completely killed. If you try to send `POST /dream-weaver` or `/docs` to port 8080 you will get a 404. You MUST change your `AppConfig.baseURL` parameter to use port **`8082`**.
---
## 1. Architecture Overview (API v2)
```
┌────────────────────┐ HTTP/S ┌──────────────────────────────┐
│ │ ── keywords ────► │ Dream Weaver Gateway v2 │
│ iPad App (Swift) │ │ FastAPI port 8082 │
│ │ ◄── PNG result ── │ dw_gateway_v2.py │
└────────────────────┘ └─────────────┬────────────────┘
│ LLM Prompt Expansion
│ (Local Ollama: Qwen 3.5 27B)
┌─────────────────────────┐
│ ComfyUI Engine │
│ port 8188 │
│ RealVisXL V5.0 Ltng │
└─────────────────────────┘
```
**Key changes in v2:**
1. The API now runs on port **`8082`** to avoid conflicts.
2. The [style](file:///F:/Workin%20In%20Progress/DESINEURON/GITLAB/Project_Velocity/comfy_engine/scripts/dreamweaver_batch_processor.py#394-414) parameter is deprecated in favor of `keywords` (array of strings) and [room_type](file:///F:/Workin%20In%20Progress/DESINEURON/GITLAB/Project_Velocity/comfy_engine/scripts/dw_gateway_v2.py#171-186).
---
## 2. Dynamic Keyword Expansion Flow
Instead of injecting keywords into a rigid template, the new backend reads the `keywords` and [room_type](file:///F:/Workin%20In%20Progress/DESINEURON/GITLAB/Project_Velocity/comfy_engine/scripts/dw_gateway_v2.py#171-186), and asks a local LLM (Qwen 3.5 27B) to act as an interior designer:
1. **User input:** `keywords: ["blue marble", "gold veins", "renaissance"]`, `room_type: "bathroom"`
2. **Backend LLM Expansion:** The LLM knows that a "bathroom" cannot have beds and needs wet-area materials. It creates a rich positive prompt: *"renaissance revival luxury interior design, blue veined marble flooring, gold brass fixtures..."*
3. **ComfyUI Generation:** The expanded prompt is sent to ComfyUI for generation.
**Supported Room Types:**
`bedroom`, `living_room`, `bathroom`, `kitchen`, `dining_room`, `home_office`, `hallway`, `balcony`.
---
## 3. API Reference — New v2 Endpoints
### BASE URL
```
http://54.172.172.2:8082
```
### 3.1 `GET /health` — Liveness Check
Call this on app launch to confirm the v2 server is up.
**Response:**
```json
{
"status": "ok",
"comfyui": true,
"gpu": "4x NVIDIA L4 (96GB VRAM)",
"model": "RealVisXL V5.0 Lightning",
"llm_expansion": true,
"version": "2.0.0"
}
```
### 3.2 `GET /room-types`
Returns all supported room types and their required design context (useful if you want to build UI tooltips).
```json
{
"room_types": {
"bedroom": {
"description": "a private sleeping space",
"key_elements": ["bed", "bedside tables", "wardrobe", "soft lighting", "textiles", "headboard"]
},
...
}
}
```
### 3.3 `POST /dream-weaver/expand` (Preview Prompt)
Use this if you want the user to **preview** the LLM's generated prompt before committing to a generation.
**Request (JSON):**
```json
{
"keywords": ["blue marble", "gold veins", "renaissance"],
"room_type": "bathroom"
}
```
**Response:**
```json
{
"style_name": "Renaissance Luxury",
"positive_prompt": "renaissance revival luxury interior design, blue veined marble flooring...",
"negative_prompt": "(worst quality, low quality...), extra windows...",
"cfg": 7.5,
"denoise": 0.72,
"steps": 30,
"source": "ollama_local"
}
```
### 3.4 `POST /dream-weaver` (Submit Generation)
Use this for the main generation flow.
**Request:** `multipart/form-data`
| Field | Type | Required | Description |
|---|---|---|---|
| [image](file:///F:/Workin%20In%20Progress/DESINEURON/GITLAB/Project_Velocity/comfy_engine/scripts/a100_deployment_executor.py#306-322) | File | ✅ | The room photo (JPEG/PNG) |
| `keywords` | String | ✅ | Comma-separated user keywords e.g. `"gold, marble, luxury"` |
| [room_type](file:///F:/Workin%20In%20Progress/DESINEURON/GITLAB/Project_Velocity/comfy_engine/scripts/dw_gateway_v2.py#171-186) | String | ✅ | e.g. `"living_room"`, `"bedroom"` |
| `additional_notes` | String | | (Optional) e.g. `"make it feel like a luxury hotel"` |
| `denoise` | Float | | (Optional) 0.50.85. If omitted, LLM decides. |
**Response:**
```json
{
"job_id": "a1b2c3d4-...",
"status": "processing",
"prompt_preview": "renaissance revival luxury interior design...",
"poll_url": "/dream-weaver/status/a1b2c3d4-...",
"result_url": "/dream-weaver/result/a1b2c3d4-..."
}
```
---
## 4. Polling & Downloading (Unchanged from v1)
**Poll Job Status:**
`GET /dream-weaver/status/{job_id}` every 2 seconds until `ready == true`.
**Download Result:**
`GET /dream-weaver/result/{job_id}` returns the raw PNG stream.
---
## 5. Updated Swift Example (v2)
```swift
func submitGenerationV2(image: UIImage, roomType: String, keywords: [String]) async throws -> GenerationJob {
let url = URL(string: "\(AppConfig.baseURL)/dream-weaver")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
let boundary = UUID().uuidString
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = Data()
// 1. Image
let imageData = image.jpegData(compressionQuality: 0.85)!
body.appendMultipartForm(boundary: boundary, name: "image", filename: "room.jpg", contentType: "image/jpeg", data: imageData)
// 2. Room Type
body.appendMultipartForm(boundary: boundary, name: "room_type", value: roomType)
// 3. Keywords
let kwString = keywords.joined(separator: ", ")
body.appendMultipartForm(boundary: boundary, name: "keywords", value: kwString)
body.append("--\(boundary)--\r\n".data(using: .utf8)!)
request.httpBody = body
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode(GenerationJob.self, from: data)
}
// Helper extension for building multipart forms cleanly
extension Data {
mutating func appendMultipartForm(boundary: String, name: String, value: String) {
self.append("--\(boundary)\r\n".data(using: .utf8)!)
self.append("Content-Disposition: form-data; name=\"\(name)\"\r\n\r\n".data(using: .utf8)!)
self.append("\(value)\r\n".data(using: .utf8)!)
}
mutating func appendMultipartForm(boundary: String, name: String, filename: String, contentType: String, data: Data) {
self.append("--\(boundary)\r\n".data(using: .utf8)!)
self.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!)
self.append("Content-Type: \(contentType)\r\n\r\n".data(using: .utf8)!)
self.append(data)
self.append("\r\n".data(using: .utf8)!)
}
}
```
---
## 6. Sayan's Action Checklist (v2)
- [ ] Change `AppConfig.baseURL` port to `8082` (e.g., `http://54.172.172.2:8082`).
- [ ] Add a UI element for the user to select the **Room Type** (`bedroom`, `living_room`, `bathroom`, etc.).
- [ ] Change the `POST /dream-weaver` payload from `{style}` to `{keywords, room_type}`.
- [ ] (Optional) Use the new `GET /dream-weaver/expand` endpoint to let the user preview and edit the AI-generated prompt before generating.