diff --git a/docs/adr/0001-kakeya-integration-loop-log.md b/docs/adr/0001-kakeya-integration-loop-log.md index 9b5128f76..9715373c9 100644 --- a/docs/adr/0001-kakeya-integration-loop-log.md +++ b/docs/adr/0001-kakeya-integration-loop-log.md @@ -1122,6 +1122,30 @@ auto-recovery. (Caveat: the ~84 G I2V model re-downloads unless `HF_HOME` is on --- +## Iteration 40 — Gap A closed: deploy PR#5 to agent.kakeya.ai + wire quality=high → true 720p I2V + +**Honesty correction:** Iter 36–39 results were from DIRECT orchestrator runs. The live public gateway +was still PR#4 (no presets/refine-mode/chunks/mci) — confirmed by `grep` on the deployed code + +`healthz mode=distributed`. So `agent.kakeya.ai` was serving distributed-tiled (~480p mix), NOT the +720p I2V I had summarized. Owned + fixed. + +**Deployed:** head repo → `main` (PR#5) then the `quality=high→I2V` follow-up; gateway restarted. +Wired `quality=high` to the **true-720p hero path**: orchestrator `--longform` forces the I2V +generative path even at chunks=1; `high` preset → `longform=True` (+ mci x2). Multi-chunk continuity +via `chunks=N` / `longform+seconds`. + +**Verified through the PUBLIC endpoint** (`agent.kakeya.ai`, not direct): +- multi-chunk: `{chunks:2,out 1280x720}` → `mode=longform continuity=i2v px=[720,1280] frames=46` → + public download ffprobe **h264 1280×720, 46f, 2.875s**. +- one-flag hero: `{quality:"high"}` → `mode=longform chunks=1 px=[720,1280] frames=47` → public + ffprobe **h264 1280×720, 47f, 1.96s**, gen≈211 s. + +**Honest tiers now:** default/`standard` = fast distributed tiled (~480p, ~2 s); `high` = true 720p I2V +generative + optical-flow (~3.5 min); `longform`/`chunks` = multi-chunk continuity (minutes×N). Gap B +(full OpenMontage agent + all skills behind the gateway; `agent_runtime=false`) remains — separate plan. + +--- + ## Open follow-ups (next iterations) - **Phase 2b — native gRPC transport.** Add an optional `kakeya` Python SDK transport for the bounded-memory long-context path (W3), behind the same tool, once the proto diff --git a/services/agent_gateway/server.py b/services/agent_gateway/server.py index 6745fa2ef..95e64e235 100644 --- a/services/agent_gateway/server.py +++ b/services/agent_gateway/server.py @@ -160,9 +160,12 @@ def _auth(x_api_key: Optional[str] = Header(default=None)): "standard": {"fw_width": 480, "fw_height": 256, "fw_frames": 13, "proposer_steps": 6, "refine_steps": 16, "out_width": 832, "out_height": 480, "frames": 25, "fps": 12, "interpolate": 1, "interp_method": "linear", "refine_mode": ""}, + # high = the true 720p generative hero path: single-chunk I2V (longform) on the CUDA i2v worker, + # + optical-flow (mci) smoothing. Slower (~minutes) but matches the validated quality. "high": {"fw_width": 512, "fw_height": 288, "fw_frames": 17, "proposer_steps": 8, - "refine_steps": 24, "out_width": 1280, "out_height": 720, "frames": 25, - "fps": 24, "interpolate": 2, "interp_method": "mci", "refine_mode": "single"}, + "refine_steps": 22, "out_width": 1280, "out_height": 720, "frames": 25, + "fps": 24, "interpolate": 2, "interp_method": "mci", "refine_mode": "", + "longform": True, "chunk_frames": 25, "chunk_overlap": 4}, } @@ -203,15 +206,17 @@ def resolved(self) -> dict: p["seed"] = self.seed p["seconds"] = self.seconds or 0.0 p["chunks"] = self.chunks or 1 - p["chunk_frames"] = self.chunk_frames or 25 - p["chunk_overlap"] = self.chunk_overlap if self.chunk_overlap is not None else 4 - # Long-form (opt-in): derive chunk count from target seconds when longform is requested. - if self.longform and p["chunks"] == 1 and p["seconds"] > 0: + p["chunk_frames"] = self.chunk_frames or p.get("chunk_frames", 25) + p["chunk_overlap"] = self.chunk_overlap if self.chunk_overlap is not None else p.get("chunk_overlap", 4) + # longform = explicit request OR preset (high). Single-chunk longform = the true-720p I2V path. + p["longform"] = bool(self.longform or p.get("longform", False)) + # Long-form: derive chunk count from target seconds when longform is requested. + if p["longform"] and p["chunks"] == 1 and p["seconds"] > 0: net = max(1, p["chunk_frames"] - p["chunk_overlap"]) want = round(p["seconds"] * p["fps"]) if want > p["chunk_frames"]: p["chunks"] = max(1, math.ceil((want - p["chunk_overlap"]) / net)) - if p["chunks"] == 1 and p["seconds"] > 0: # single-pass: seconds drives frame count + if not p["longform"] and p["chunks"] == 1 and p["seconds"] > 0: # single-pass: seconds->frames p["frames"] = max(2, round(p["seconds"] * p["fps"])) p["quality"] = self.quality return p @@ -252,9 +257,9 @@ def _run_video_job(job: Job): cmd += ["--seconds", str(p["seconds"])] if p.get("refine_mode"): # quality preset / explicit override of refine topology cmd += ["--refine-mode", p["refine_mode"]] - if p.get("chunks", 1) > 1: # long-form (autoregressive I2V continuity) - cmd += ["--chunks", str(p["chunks"]), "--chunk-frames", str(p["chunk_frames"]), - "--chunk-overlap", str(p["chunk_overlap"])] + if p.get("longform") or p.get("chunks", 1) > 1: # I2V generative path (single or multi-chunk) + cmd += ["--longform", "--chunks", str(p.get("chunks", 1)), + "--chunk-frames", str(p["chunk_frames"]), "--chunk-overlap", str(p["chunk_overlap"])] if POOL_MODE: cmd.append("--no-refine") # each pooled worker is a single framework-only GPU (Mac MLX) elif GW_MODE == "pipeline": @@ -412,15 +417,32 @@ def index(): border:1px solid #1c2942;border-radius:10px;padding:12px;font-size:12.5px;color:#a9c2e6} video{width:100%;border-radius:12px;margin-top:12px;background:#000} input[type=password]{padding:10px;border-radius:8px;border:1px solid #2a3a59;background:#0e1830;color:#e7eefc} +select{padding:10px;border-radius:8px;border:1px solid #2a3a59;background:#0e1830;color:#e7eefc;font:inherit} +label{color:#8fa6c8;font-size:13px;display:block;margin-bottom:4px} +.opts{display:flex;gap:14px;flex-wrap:wrap;margin-top:12px}
Describe a clip. The distributed cluster (MLX proposer + CUDA refiner) renders it.
+Describe a clip. The distributed cluster (MLX proposer + CUDA / I2V refiner) renders it.
+Direct text→video via /v1/videos. First render can take a few minutes.
High = native 720p generative (I2V) — best quality, a few minutes. Standard = fast ~480p draft. Longer = multi-shot I2V continuity (minutes × shots).