mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-23 04:09:49 +00:00
feat(xai): add Grok Imagine video generation (/v1/videos) + CLI
Async video job proxy mirroring the existing image-generation layer split:
Next routes → src/sse/handlers/videoGeneration.js (auth gate, account
fallback loop, refresh persistence) → open-sse/handlers/videoCore.js
(transparent upstream proxy, 401 refresh-once/retry-once, secret sanitization).
- POST /v1/videos/{generations,edits,extensions}: byte-exact body forward
(JSON + multipart), request_id passthrough, Idempotency-Key forwarded
- GET /v1/videos/{request_id}: status/progress/video.url passthrough
- Register grok-imagine-video (kind: "video"); add "video" to MODEL_TYPE_TO_KIND
so video models stay out of chat lists (also fixes runwayml leak)
- 9router xai video CLI: submit → poll → atomic MP4 download
- No auto-retry of creation POSTs (billable jobs); rotate accounts only on
401/403/429; sanitize Bearer tokens + credential values from errors/logs
Closes #1285
This commit is contained in:
@@ -94,6 +94,7 @@ const MODEL_TYPE_TO_KIND = {
|
||||
embedding: "embedding",
|
||||
stt: "stt",
|
||||
imageToText: "imageToText",
|
||||
video: "video",
|
||||
};
|
||||
|
||||
function modelKind(model) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { handleVideoGet } from "@/sse/handlers/videoGeneration.js";
|
||||
|
||||
export async function OPTIONS() {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** GET /v1/videos/{request_id} - poll async video job status (xAI Grok Imagine) */
|
||||
export async function GET(request, { params }) {
|
||||
const { id } = await params;
|
||||
return await handleVideoGet(request, id);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { handleVideoCreate } from "@/sse/handlers/videoGeneration.js";
|
||||
|
||||
export async function OPTIONS() {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** POST /v1/videos/edits - async video edit (xAI Grok Imagine) */
|
||||
export async function POST(request) {
|
||||
return await handleVideoCreate(request, "edits");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { handleVideoCreate } from "@/sse/handlers/videoGeneration.js";
|
||||
|
||||
export async function OPTIONS() {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** POST /v1/videos/extensions - async video extension (xAI Grok Imagine) */
|
||||
export async function POST(request) {
|
||||
return await handleVideoCreate(request, "extensions");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { handleVideoCreate } from "@/sse/handlers/videoGeneration.js";
|
||||
|
||||
export async function OPTIONS() {
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** POST /v1/videos/generations - async video generation (xAI Grok Imagine) */
|
||||
export async function POST(request) {
|
||||
return await handleVideoCreate(request, "generations");
|
||||
}
|
||||
Reference in New Issue
Block a user