Commit 5c88ba5
authored
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)
17 files changed
Lines changed: 5336 additions & 189 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
5 | 12 | | |
6 | 13 | | |
7 | 14 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
40 | 42 | | |
41 | 43 | | |
42 | 44 | | |
| |||
0 commit comments