Skip to content

Commit 5c88ba5

Browse files
authored
feat(video): native Google Veo + xAI Grok Imagine async video providers (#278) (#282)
Closes #278. Adds first-class aimock support for two async video-generation providers, mirroring the existing Sora / OpenRouter / fal job-lifecycle model — replay **and** live record-mode proxy for both. ## Google Veo (Gemini) - `POST /v1beta/models/{model}:predictLongRunning` → `{ name }`, then `GET /v1beta/operations/{name}` poll → `{ done:false }` … `{ done:true, response.generateVideoResponse.generatedSamples[].video.uri }`, with poll-count progression. - Files-API `uri` is served as-is (aimock does not proxy the video bytes — Veo's envelope carries no cost field). - Record mode forwards 1:1 to the configured `veo` upstream and eager-captures the fixture on `done:true`. ## xAI Grok Imagine - `POST /v1/videos/generations` → `{ request_id }` (multipart rejected with 400), then `GET /v1/videos/{request_id}` → `{ status: pending|done|failed|expired, progress, video, usage.cost_in_usd_ticks }`. Progress synthesized from poll count; `cost_in_usd_ticks` = USD × 1e10. - Shares `/v1/videos/{id}` with Sora: job-map-first lookup, falling through to the **unchanged** Sora handler on a miss (pinned byte-for-byte by a test). - Record mode forwards 1:1 to the configured `grok` upstream and eager-captures on terminal status. Shared proxy helpers were extracted into `src/video-proxy-shared.ts` (behavior-preserving; openrouter-video re-pointed at it, its 233 tests green before & after). ## Verification - Full suite **4113 passing** (127 files), build + exports + lint + format + `tsc --noEmit` all clean. - Both providers have red-green-proven replay + record tests against a credential-free fake local upstream (no real Veo/xAI keys needed). - Reviewed via a 4-round, 9-agent-per-round CR loop converged to zero (Procedure 3 bucket-c audit: 0 promotions). Behavioral fixes (failed-seed progress, status-dispatch error journaling for both providers, empty-url placeholder) each landed with a red→green covering test. ## Known follow-ups (not blocking) - **Verify** `@google/genai` forwards `x-test-id` on `operations.getVideosOperation` polls; if it does not, Veo would need testId conveyance via the operation name (like OpenRouter's `testIdSuffix`) for non-default-testId clients. Consistent with Sora's contract today. - Minor hardening logged: guard Grok's poll-URL build like Veo's; reconcile the capture-latch reset discipline across the two; `Number.isFinite` guards + warns on malformed upstream duration/cost. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
2 parents babfbc2 + d00981c commit 5c88ba5

17 files changed

Lines changed: 5336 additions & 189 deletions

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- Native Google Veo async video lifecycle mock — `POST /v1beta/models/{model}:predictLongRunning` submit, `GET /v1beta/operations/{name}` poll through `done:false → done:true`, poll-count progression via `veoVideo`; the Files-API `uri` is served as-is (aimock never proxies or downloads video bytes) (#278)
8+
- Record-mode live proxying for the Veo surface (`record.providers.veo`) — submit and poll forwarded 1:1, eager fixture capture of the Files-API uri on `done:true`; captured operations replay later (#278)
9+
- Native xAI Grok Imagine async video lifecycle mock — `POST /v1/videos/generations` submit (JSON-only; multipart rejected with 400), `GET /v1/videos/{request_id}` poll through `pending → done | failed | expired` with synthesized `progress`, `grokVideo` progression, `cost_in_usd_ticks` units, and a Sora-safe `/v1/videos/{id}` dispatch that leaves the OpenAI video surface unchanged (#278)
10+
- Record-mode live proxying for the Grok surface (`record.providers.grok`) — submit and poll forwarded 1:1, eager fixture capture of url/duration/cost on `done`, `failed` persisted, `expired` passed through; captured jobs replay later (#278)
11+
512
## [1.34.0] - 2026-06-24
613

714
### Changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Run them all on one port with `npx @copilotkit/aimock --config aimock.json`, or
5252
- **Timing-aware recording and replay** — Recorded fixtures capture per-frame arrival timestamps; replay uses recorded timings for approximate timing reproduction based on recorded TTFT and inter-frame cadence (replay chunk count may differ from recording — TTFT and average pace are preserved, not per-token fidelity) with configurable `--replay-speed` multiplier
5353
- **[Multi-turn Conversations](https://aimock.copilotkit.dev/multi-turn)** — Record and replay multi-turn traces with tool rounds; match distinct turns via `turnIndex`, `hasToolResult`, `toolCallId`, `sequenceIndex`, `systemMessage` (gate on host-supplied agent context), or custom predicates
5454
- **[12 providers across 14 API surfaces](https://aimock.copilotkit.dev/docs)** — OpenAI Chat, OpenAI Responses, OpenAI Realtime (GA + Beta shim), Claude, Gemini (REST + embedContent), Gemini Live, Gemini Interactions, Azure, Bedrock, Vertex AI, Ollama (chat + embeddings), Cohere (chat + embed), ElevenLabs TTS — full streaming support
55-
- **Multimedia APIs**[image generation](https://aimock.copilotkit.dev/images) (DALL-E, Imagen), [image editing](https://aimock.copilotkit.dev/images) (/v1/images/edits), [text-to-speech](https://aimock.copilotkit.dev/speech) (OpenAI + ElevenLabs), [audio transcription](https://aimock.copilotkit.dev/transcription), [audio translation](https://aimock.copilotkit.dev/transcription) (/v1/audio/translations), [video generation](https://aimock.copilotkit.dev/video), [OpenRouter video generation](https://aimock.copilotkit.dev/openrouter-video) (/api/v1/videos with async job lifecycle), [fal.ai](https://aimock.copilotkit.dev/fal-ai) (image / video / audio with queue lifecycle)
55+
- **Multimedia APIs**[image generation](https://aimock.copilotkit.dev/images) (DALL-E, Imagen), [image editing](https://aimock.copilotkit.dev/images) (/v1/images/edits), [text-to-speech](https://aimock.copilotkit.dev/speech) (OpenAI + ElevenLabs), [audio transcription](https://aimock.copilotkit.dev/transcription), [audio translation](https://aimock.copilotkit.dev/transcription) (/v1/audio/translations), [video generation](https://aimock.copilotkit.dev/video), [OpenRouter video generation](https://aimock.copilotkit.dev/openrouter-video) (/api/v1/videos with async job lifecycle), [Google Veo video generation](https://aimock.copilotkit.dev/veo-video) (:predictLongRunning + /v1beta/operations async lifecycle), [Grok Imagine video generation](https://aimock.copilotkit.dev/grok-video) (/v1/videos/generations with async job lifecycle), [fal.ai](https://aimock.copilotkit.dev/fal-ai) (image / video / audio with queue lifecycle)
5656
- **[MCP](https://aimock.copilotkit.dev/mcp-mock) / [A2A](https://aimock.copilotkit.dev/a2a-mock) / [AG-UI](https://aimock.copilotkit.dev/agui-mock) / [Vector](https://aimock.copilotkit.dev/vector-mock)** — Mock every protocol your AI agents use
5757
- **[Chaos Testing](https://aimock.copilotkit.dev/chaos-testing)** — 500 errors, malformed JSON, mid-stream disconnects at any probability
5858
- **Per-Request Strict Mode**`X-AIMock-Strict` header overrides the server-level `--strict` flag per request (`true`/`1` = strict, `false`/`0` = lenient)

docs/grok-video/index.html

Lines changed: 308 additions & 0 deletions
Large diffs are not rendered by default.

docs/sidebar.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
{ label: "Audio Transcription", href: "/transcription" },
3838
{ label: "Video Generation", href: "/video" },
3939
{ label: "OpenRouter Video", href: "/openrouter-video" },
40+
{ label: "Google Veo Video", href: "/veo-video" },
41+
{ label: "Grok Imagine Video", href: "/grok-video" },
4042
{ label: "fal.ai", href: "/fal-ai" },
4143
],
4244
},

0 commit comments

Comments
 (0)