#7 Task completed. Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local> Reviewed-on: sagnik/Project_Velocity#8
8.7 KiB
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-weaveror/docsto port 8080 you will get a 404. You MUST change yourAppConfig.baseURLparameter to use port8082.
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:
- The API now runs on port
8082to avoid conflicts. - The style parameter is deprecated in favor of
keywords(array of strings) and room_type.
2. Dynamic Keyword Expansion Flow
Instead of injecting keywords into a rigid template, the new backend reads the keywords and room_type, and asks a local LLM (Qwen 3.5 27B) to act as an interior designer:
- User input:
keywords: ["blue marble", "gold veins", "renaissance"],room_type: "bathroom" - 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..."
- 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:
{
"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).
{
"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):
{
"keywords": ["blue marble", "gold veins", "renaissance"],
"room_type": "bathroom"
}
Response:
{
"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 | ✅ | The room photo (JPEG/PNG) |
keywords |
String | ✅ | Comma-separated user keywords e.g. "gold, marble, luxury" |
| room_type | String | ✅ | e.g. "living_room", "bedroom" |
additional_notes |
String | ➕ | (Optional) e.g. "make it feel like a luxury hotel" |
denoise |
Float | ➕ | (Optional) 0.5–0.85. If omitted, LLM decides. |
Response:
{
"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)
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.baseURLport to8082(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-weaverpayload from{style}to{keywords, room_type}. - (Optional) Use the new
GET /dream-weaver/expandendpoint to let the user preview and edit the AI-generated prompt before generating.