Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ endpoint actually accepts, proven by one live generation through the adapter.
moderation flags abstract prompts ("a red circle on white") as violence, and
the resulting 400 looks like a broken model.

7. **Retiring a model.** Remove the catalog entry and the `ImageModel` union
member, and add the id to `src/services/llm/types/RetiredMediaModels.ts`
with the provider's documented successor and every provider that served
it. Saved defaults, conversation settings and `generateImage` calls that
still name it are mapped there. If the removed entry was a catalog's first,
put the adapter default first instead: the tool and the chat picker fall
back to the first entry.

## Guidelines
- Pattern: Google's image docs show only Interactions API samples, but
`GeminiImageAdapter` calls `generateContent`. Before you add a Gemini image
Expand Down
38 changes: 25 additions & 13 deletions .claude/skills/nexus-model-updates/protocols/add-video-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ provider accepts, on a transport the adapter already uses.

## Steps

1. **Check the transport first.** `GoogleVideoAdapter` uses
`models/<id>:predictLongRunning`. Google's newer video models are served
only by the Interactions API (`POST /v1beta/interactions`), and that is
new adapter work, not a catalog entry. `OpenRouterVideoAdapter` speaks
OpenRouter's unified `POST /api/v1/videos`, so any model in its video
catalog uses the same request shape.
1. **Check the transport first.** `GoogleVideoAdapter` speaks Google's
Interactions API (`POST /v1beta/interactions` with `background: true`, then
`GET /v1beta/interactions/{id}`), which is how Gemini Omni Flash is served.
A Google video model on another surface (Veo's `predictLongRunning`, or a
Vertex-only id) is new adapter work, not a catalog entry.
`OpenRouterVideoAdapter` speaks OpenRouter's unified `POST /api/v1/videos`,
so any model in its video catalog uses the same request shape.

2. **Source the facts.**

Expand All @@ -32,14 +33,18 @@ provider accepts, on a transport the adapter already uses.
"frames", m.get("supported_frame_images"))'
```

For Google direct, the parameter table on ai.google.dev/gemini-api/docs/video
is the source, and `/docs/deprecations` gives shutdown dates. Read it per
model: Veo on the Gemini API accepts `16:9`/`9:16` only, even though other
routes add `1:1`.
For Google direct, the model's guide (for Omni, ai.google.dev/gemini-api/docs/omni)
and the `VideoResponseFormat` schema in
https://ai.google.dev/static/api/interactions.openapi.json are the source,
and `/docs/deprecations` gives shutdown dates. Omni accepts `16:9`/`9:16`
only and a `duration` in google-duration format (`"8s"`). Do not infer the
transport from the keyed model listing: it reports Omni with
`generateContent`, and it keeps listing preview ids past their shutdown
date. The guide names the transport; the deprecations page decides removal.

3. **Fit the entry to the unions.** `VideoAspectRatio` and `VideoResolution`
are narrow, closed unions. Declare the intersection of the listing and the
union. A model with no value in the intersection (for example a `2K`-only
are narrow, closed unions (`360p` exists for Omni; OpenRouter's parser
still drops it). Declare the intersection of the listing and the union. A model with no value in the intersection (for example a `2K`-only
model) needs a type change and is not a catalog-only addition. OpenRouter's
resolution enum is case-sensitive (`4K`), and the adapter maps the internal
`4k` to it. Keep that mapping when you touch `submitJob`.
Expand All @@ -57,8 +62,15 @@ provider accepts, on a transport the adapter already uses.
`tests/unit/VideoGenerationService.test.ts` must still pass.

6. **Live call.** `tests/debug/video-generation-live-smoke.test.ts` drives the
real adapters. Video generation is billed per second, so run it only with
real adapters (OpenRouter by default; add `VIDEO_SMOKE_GOOGLE=1` and a
`GEMINI_API_KEY` for Gemini Omni Flash — see the file header). Video generation is billed per second, so run it only with
the owner's go-ahead. Without that run, report the entry as unverified.

7. **Retiring a model.** Remove its entry and add it to
`src/services/llm/types/RetiredMediaModels.ts` with the provider-documented
successor. Saved defaults, conversations and tool calls that still name it
are mapped there at load and call time; the catalog alone would turn them
into "not available" errors.

## Next
`verify-model.md` steps 1–3, then `self-refine.md`.
2 changes: 2 additions & 0 deletions .claude/skills/nexus-model-updates/refinement-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,5 @@ Append-only record of changes made by `protocols/self-refine.md`. Newest on top.
- 2026-10-13: Authenticated model metadata can expose a lower output ceiling than streaming documentation. Used the keyed listing and kept transport-specific caps separate; no protocol change needed.

- 2026-10-14 | Updating the image and video catalogs, the skill had no route for video models: they live in a single static `VIDEO_MODELS` array in `src/services/llm/types/VideoTypes.ts` that the gate does not see. Several problems in that file were only visible in the provider's listing: Veo routes declared `1:1`, which no Veo route accepts; the OpenRouter adapter sent `4k` to a case-sensitive `4K` enum; and Google's Veo 3.1 previews shut down on 2026-10-22 with an Interactions-API-only successor. Gemini image docs now show only Interactions samples while the adapter calls `generateContent`, and there was no Google key available to check `supportedGenerationMethods`. | Added `protocols/add-video-model.md` and a SKILL.md workflow row, plus a guideline in `add-image-model.md` to confirm `generateContent` before adding a Gemini image id. | Files: `SKILL.md`, `protocols/add-video-model.md`, `protocols/add-image-model.md`.

- 2026-10-14 | Replacing the Google Veo 3.1 previews with Gemini Omni Flash and removing shut-down image ids. The keyed Google listing reported `gemini-omni-1.1-flash` with `generateContent` although it is served by the Interactions API, and still listed the Veo and Nano Banana preview ids past or near their shutdown dates, so neither the listing's methods nor its presence settles transport or retirement. Removing ids also needed somewhere to send saved settings and tool calls that still name them. A paid run (one 3 s 360p Omni clip, one OpenAI and one Gemini image) passed through the shipped adapters. | Rewrote `add-video-model.md` step 1 for the Interactions transport, added the listing caveat, and a "retiring a model" step to both media protocols pointing at `RetiredMediaModels.ts`. | Files: `protocols/add-video-model.md`, `protocols/add-image-model.md`, this log.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ endpoint actually accepts, proven by one live generation through the adapter.
moderation flags abstract prompts ("a red circle on white") as violence, and
the resulting 400 looks like a broken model.

7. **Retiring a model.** Remove the catalog entry and the `ImageModel` union
member, and add the id to `src/services/llm/types/RetiredMediaModels.ts`
with the provider's documented successor and every provider that served
it. Saved defaults, conversation settings and `generateImage` calls that
still name it are mapped there. If the removed entry was a catalog's first,
put the adapter default first instead: the tool and the chat picker fall
back to the first entry.

## Guidelines
- Pattern: Google's image docs show only Interactions API samples, but
`GeminiImageAdapter` calls `generateContent`. Before you add a Gemini image
Expand Down
38 changes: 25 additions & 13 deletions .cline/skills/nexus-model-updates/protocols/add-video-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ provider accepts, on a transport the adapter already uses.

## Steps

1. **Check the transport first.** `GoogleVideoAdapter` uses
`models/<id>:predictLongRunning`. Google's newer video models are served
only by the Interactions API (`POST /v1beta/interactions`), and that is
new adapter work, not a catalog entry. `OpenRouterVideoAdapter` speaks
OpenRouter's unified `POST /api/v1/videos`, so any model in its video
catalog uses the same request shape.
1. **Check the transport first.** `GoogleVideoAdapter` speaks Google's
Interactions API (`POST /v1beta/interactions` with `background: true`, then
`GET /v1beta/interactions/{id}`), which is how Gemini Omni Flash is served.
A Google video model on another surface (Veo's `predictLongRunning`, or a
Vertex-only id) is new adapter work, not a catalog entry.
`OpenRouterVideoAdapter` speaks OpenRouter's unified `POST /api/v1/videos`,
so any model in its video catalog uses the same request shape.

2. **Source the facts.**

Expand All @@ -32,14 +33,18 @@ provider accepts, on a transport the adapter already uses.
"frames", m.get("supported_frame_images"))'
```

For Google direct, the parameter table on ai.google.dev/gemini-api/docs/video
is the source, and `/docs/deprecations` gives shutdown dates. Read it per
model: Veo on the Gemini API accepts `16:9`/`9:16` only, even though other
routes add `1:1`.
For Google direct, the model's guide (for Omni, ai.google.dev/gemini-api/docs/omni)
and the `VideoResponseFormat` schema in
https://ai.google.dev/static/api/interactions.openapi.json are the source,
and `/docs/deprecations` gives shutdown dates. Omni accepts `16:9`/`9:16`
only and a `duration` in google-duration format (`"8s"`). Do not infer the
transport from the keyed model listing: it reports Omni with
`generateContent`, and it keeps listing preview ids past their shutdown
date. The guide names the transport; the deprecations page decides removal.

3. **Fit the entry to the unions.** `VideoAspectRatio` and `VideoResolution`
are narrow, closed unions. Declare the intersection of the listing and the
union. A model with no value in the intersection (for example a `2K`-only
are narrow, closed unions (`360p` exists for Omni; OpenRouter's parser
still drops it). Declare the intersection of the listing and the union. A model with no value in the intersection (for example a `2K`-only
model) needs a type change and is not a catalog-only addition. OpenRouter's
resolution enum is case-sensitive (`4K`), and the adapter maps the internal
`4k` to it. Keep that mapping when you touch `submitJob`.
Expand All @@ -57,8 +62,15 @@ provider accepts, on a transport the adapter already uses.
`tests/unit/VideoGenerationService.test.ts` must still pass.

6. **Live call.** `tests/debug/video-generation-live-smoke.test.ts` drives the
real adapters. Video generation is billed per second, so run it only with
real adapters (OpenRouter by default; add `VIDEO_SMOKE_GOOGLE=1` and a
`GEMINI_API_KEY` for Gemini Omni Flash — see the file header). Video generation is billed per second, so run it only with
the owner's go-ahead. Without that run, report the entry as unverified.

7. **Retiring a model.** Remove its entry and add it to
`src/services/llm/types/RetiredMediaModels.ts` with the provider-documented
successor. Saved defaults, conversations and tool calls that still name it
are mapped there at load and call time; the catalog alone would turn them
into "not available" errors.

## Next
`verify-model.md` steps 1–3, then `self-refine.md`.
2 changes: 2 additions & 0 deletions .cline/skills/nexus-model-updates/refinement-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,5 @@ Append-only record of changes made by `protocols/self-refine.md`. Newest on top.
- 2026-10-13: Authenticated model metadata can expose a lower output ceiling than streaming documentation. Used the keyed listing and kept transport-specific caps separate; no protocol change needed.

- 2026-10-14 | Updating the image and video catalogs, the skill had no route for video models: they live in a single static `VIDEO_MODELS` array in `src/services/llm/types/VideoTypes.ts` that the gate does not see. Several problems in that file were only visible in the provider's listing: Veo routes declared `1:1`, which no Veo route accepts; the OpenRouter adapter sent `4k` to a case-sensitive `4K` enum; and Google's Veo 3.1 previews shut down on 2026-10-22 with an Interactions-API-only successor. Gemini image docs now show only Interactions samples while the adapter calls `generateContent`, and there was no Google key available to check `supportedGenerationMethods`. | Added `protocols/add-video-model.md` and a SKILL.md workflow row, plus a guideline in `add-image-model.md` to confirm `generateContent` before adding a Gemini image id. | Files: `SKILL.md`, `protocols/add-video-model.md`, `protocols/add-image-model.md`.

- 2026-10-14 | Replacing the Google Veo 3.1 previews with Gemini Omni Flash and removing shut-down image ids. The keyed Google listing reported `gemini-omni-1.1-flash` with `generateContent` although it is served by the Interactions API, and still listed the Veo and Nano Banana preview ids past or near their shutdown dates, so neither the listing's methods nor its presence settles transport or retirement. Removing ids also needed somewhere to send saved settings and tool calls that still name them. A paid run (one 3 s 360p Omni clip, one OpenAI and one Gemini image) passed through the shipped adapters. | Rewrote `add-video-model.md` step 1 for the Interactions transport, added the listing caveat, and a "retiring a model" step to both media protocols pointing at `RetiredMediaModels.ts`. | Files: `protocols/add-video-model.md`, `protocols/add-image-model.md`, this log.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ endpoint actually accepts, proven by one live generation through the adapter.
moderation flags abstract prompts ("a red circle on white") as violence, and
the resulting 400 looks like a broken model.

7. **Retiring a model.** Remove the catalog entry and the `ImageModel` union
member, and add the id to `src/services/llm/types/RetiredMediaModels.ts`
with the provider's documented successor and every provider that served
it. Saved defaults, conversation settings and `generateImage` calls that
still name it are mapped there. If the removed entry was a catalog's first,
put the adapter default first instead: the tool and the chat picker fall
back to the first entry.

## Guidelines
- Pattern: Google's image docs show only Interactions API samples, but
`GeminiImageAdapter` calls `generateContent`. Before you add a Gemini image
Expand Down
38 changes: 25 additions & 13 deletions .codex/skills/nexus-model-updates/protocols/add-video-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ provider accepts, on a transport the adapter already uses.

## Steps

1. **Check the transport first.** `GoogleVideoAdapter` uses
`models/<id>:predictLongRunning`. Google's newer video models are served
only by the Interactions API (`POST /v1beta/interactions`), and that is
new adapter work, not a catalog entry. `OpenRouterVideoAdapter` speaks
OpenRouter's unified `POST /api/v1/videos`, so any model in its video
catalog uses the same request shape.
1. **Check the transport first.** `GoogleVideoAdapter` speaks Google's
Interactions API (`POST /v1beta/interactions` with `background: true`, then
`GET /v1beta/interactions/{id}`), which is how Gemini Omni Flash is served.
A Google video model on another surface (Veo's `predictLongRunning`, or a
Vertex-only id) is new adapter work, not a catalog entry.
`OpenRouterVideoAdapter` speaks OpenRouter's unified `POST /api/v1/videos`,
so any model in its video catalog uses the same request shape.

2. **Source the facts.**

Expand All @@ -32,14 +33,18 @@ provider accepts, on a transport the adapter already uses.
"frames", m.get("supported_frame_images"))'
```

For Google direct, the parameter table on ai.google.dev/gemini-api/docs/video
is the source, and `/docs/deprecations` gives shutdown dates. Read it per
model: Veo on the Gemini API accepts `16:9`/`9:16` only, even though other
routes add `1:1`.
For Google direct, the model's guide (for Omni, ai.google.dev/gemini-api/docs/omni)
and the `VideoResponseFormat` schema in
https://ai.google.dev/static/api/interactions.openapi.json are the source,
and `/docs/deprecations` gives shutdown dates. Omni accepts `16:9`/`9:16`
only and a `duration` in google-duration format (`"8s"`). Do not infer the
transport from the keyed model listing: it reports Omni with
`generateContent`, and it keeps listing preview ids past their shutdown
date. The guide names the transport; the deprecations page decides removal.

3. **Fit the entry to the unions.** `VideoAspectRatio` and `VideoResolution`
are narrow, closed unions. Declare the intersection of the listing and the
union. A model with no value in the intersection (for example a `2K`-only
are narrow, closed unions (`360p` exists for Omni; OpenRouter's parser
still drops it). Declare the intersection of the listing and the union. A model with no value in the intersection (for example a `2K`-only
model) needs a type change and is not a catalog-only addition. OpenRouter's
resolution enum is case-sensitive (`4K`), and the adapter maps the internal
`4k` to it. Keep that mapping when you touch `submitJob`.
Expand All @@ -57,8 +62,15 @@ provider accepts, on a transport the adapter already uses.
`tests/unit/VideoGenerationService.test.ts` must still pass.

6. **Live call.** `tests/debug/video-generation-live-smoke.test.ts` drives the
real adapters. Video generation is billed per second, so run it only with
real adapters (OpenRouter by default; add `VIDEO_SMOKE_GOOGLE=1` and a
`GEMINI_API_KEY` for Gemini Omni Flash — see the file header). Video generation is billed per second, so run it only with
the owner's go-ahead. Without that run, report the entry as unverified.

7. **Retiring a model.** Remove its entry and add it to
`src/services/llm/types/RetiredMediaModels.ts` with the provider-documented
successor. Saved defaults, conversations and tool calls that still name it
are mapped there at load and call time; the catalog alone would turn them
into "not available" errors.

## Next
`verify-model.md` steps 1–3, then `self-refine.md`.
2 changes: 2 additions & 0 deletions .codex/skills/nexus-model-updates/refinement-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,5 @@ Append-only record of changes made by `protocols/self-refine.md`. Newest on top.
- 2026-10-13: Authenticated model metadata can expose a lower output ceiling than streaming documentation. Used the keyed listing and kept transport-specific caps separate; no protocol change needed.

- 2026-10-14 | Updating the image and video catalogs, the skill had no route for video models: they live in a single static `VIDEO_MODELS` array in `src/services/llm/types/VideoTypes.ts` that the gate does not see. Several problems in that file were only visible in the provider's listing: Veo routes declared `1:1`, which no Veo route accepts; the OpenRouter adapter sent `4k` to a case-sensitive `4K` enum; and Google's Veo 3.1 previews shut down on 2026-10-22 with an Interactions-API-only successor. Gemini image docs now show only Interactions samples while the adapter calls `generateContent`, and there was no Google key available to check `supportedGenerationMethods`. | Added `protocols/add-video-model.md` and a SKILL.md workflow row, plus a guideline in `add-image-model.md` to confirm `generateContent` before adding a Gemini image id. | Files: `SKILL.md`, `protocols/add-video-model.md`, `protocols/add-image-model.md`.

- 2026-10-14 | Replacing the Google Veo 3.1 previews with Gemini Omni Flash and removing shut-down image ids. The keyed Google listing reported `gemini-omni-1.1-flash` with `generateContent` although it is served by the Interactions API, and still listed the Veo and Nano Banana preview ids past or near their shutdown dates, so neither the listing's methods nor its presence settles transport or retirement. Removing ids also needed somewhere to send saved settings and tool calls that still name them. A paid run (one 3 s 360p Omni clip, one OpenAI and one Gemini image) passed through the shipped adapters. | Rewrote `add-video-model.md` step 1 for the Interactions transport, added the listing caveat, and a "retiring a model" step to both media protocols pointing at `RetiredMediaModels.ts`. | Files: `protocols/add-video-model.md`, `protocols/add-image-model.md`, this log.
Loading
Loading