119 lines
7.1 KiB
Markdown

## ADDED Requirements
### Requirement: Group image generation capability
The system SHALL store a group-level `allow_image_generation` capability flag and SHALL expose it through admin group create, update, list, and detail APIs.
#### Scenario: New group defaults to image generation disabled
- **WHEN** an admin creates a group without providing `allow_image_generation`
- **THEN** the persisted group has `allow_image_generation=false`
#### Scenario: Existing image-capable platform groups are backfilled
- **WHEN** the migration is applied to existing groups
- **THEN** existing `openai`, `gemini`, and `antigravity` groups have `allow_image_generation=true`
- **AND** existing `anthropic` groups have `allow_image_generation=false`
#### Scenario: Admin enables image generation on an ordinary coding group
- **WHEN** an admin updates an `openai` group with `allow_image_generation=true`
- **THEN** the group can use image generation paths subject to the billing requirements
#### Scenario: Admin disables image generation on an ordinary coding group
- **WHEN** an admin updates an `openai` group with `allow_image_generation=false`
- **THEN** the group can still use non-image text model requests
- **AND** image generation intents are denied before upstream dispatch
### Requirement: Image generation intent detection
The system SHALL classify a request as an image generation intent before upstream account scheduling when the endpoint or request body can produce generated images.
#### Scenario: Images endpoint is an image generation intent
- **WHEN** a request targets `/v1/images/generations`, `/v1/images/edits`, `/images/generations`, or `/images/edits`
- **THEN** the request is classified as an image generation intent
#### Scenario: Responses request with image-only model is an image generation intent
- **WHEN** a `/v1/responses` request has a requested model whose normalized name starts with `gpt-image-`
- **THEN** the request is classified as an image generation intent before any model rewrite
#### Scenario: Responses request with image_generation tool is an image generation intent
- **WHEN** a `/v1/responses` request contains any `tools[]` entry with `type == "image_generation"`
- **THEN** the request is classified as an image generation intent
#### Scenario: Responses request with image_generation tool_choice is an image generation intent
- **WHEN** a `/v1/responses` request contains `tool_choice` that explicitly selects `image_generation`
- **THEN** the request is classified as an image generation intent even if `tools[]` is malformed or absent
#### Scenario: Generic tool_choice required is not sufficient by itself
- **WHEN** a `/v1/responses` request contains `tool_choice="required"`
- **AND** the request does not contain an `image_generation` tool
- **THEN** the request is not classified as an image generation intent because of `tool_choice` alone
#### Scenario: Text-only gpt-5.4 request is not an image generation intent
- **WHEN** a `/v1/responses` request uses `model="gpt-5.4"` or `model="gpt-5.5"` without `image_generation` tool and without image `tool_choice`
- **THEN** the request is not classified as an image generation intent
#### Scenario: Intent is checked before and after service-side mutation
- **WHEN** the service mutates a `/v1/responses` request by injecting `image_generation` or rewriting `gpt-image-*` to a Responses text model plus image tool
- **THEN** the final mutated request is checked against the same image generation intent rules before upstream dispatch
### Requirement: Disabled groups reject explicit image generation
The system SHALL reject explicit image generation intents for groups with `allow_image_generation=false` before selecting or calling an upstream account.
#### Scenario: Disabled group rejects Images API
- **WHEN** a group has `allow_image_generation=false`
- **AND** a user calls `/v1/images/generations`
- **THEN** the system returns HTTP 403 with error type `permission_error`
- **AND** no upstream account is selected
- **AND** no usage log is written
#### Scenario: Disabled group rejects Responses image tool
- **WHEN** a group has `allow_image_generation=false`
- **AND** a user calls `/v1/responses` with `tools:[{"type":"image_generation"}]`
- **THEN** the system returns HTTP 403 with error type `permission_error`
- **AND** no upstream account is selected
- **AND** no usage log is written
#### Scenario: Disabled group rejects Responses image-only model rewrite
- **WHEN** a group has `allow_image_generation=false`
- **AND** a user calls `/v1/responses` with `model` starting with `gpt-image-`
- **THEN** the system returns HTTP 403 with error type `permission_error`
- **AND** the request is not rewritten to a text Responses model
#### Scenario: Disabled group permits normal coding request
- **WHEN** a group has `allow_image_generation=false`
- **AND** a user calls `/v1/responses` with `model="gpt-5.4"` and no image generation intent
- **THEN** the request proceeds through the normal text forwarding path
### Requirement: Codex image tool injection respects group capability
The system SHALL only inject the OpenAI Responses `image_generation` tool and bridge instructions for Codex clients when the request group has `allow_image_generation=true`.
#### Scenario: Codex request in enabled group receives image tool
- **WHEN** a Codex CLI `/v1/responses` request belongs to a group with `allow_image_generation=true`
- **AND** the request has no `image_generation` tool
- **THEN** the system injects the existing `image_generation` tool payload
- **AND** the system appends the existing Codex image bridge instructions
#### Scenario: Codex request in disabled group does not receive image tool
- **WHEN** a Codex CLI `/v1/responses` request belongs to a group with `allow_image_generation=false`
- **AND** the request has no explicit image generation intent
- **THEN** the system does not inject `image_generation`
- **AND** the system does not append image bridge instructions
- **AND** the request proceeds as a text request
#### Scenario: Codex explicit image request in disabled group is denied
- **WHEN** a Codex CLI `/v1/responses` request belongs to a group with `allow_image_generation=false`
- **AND** the request explicitly contains `image_generation`
- **THEN** the system returns HTTP 403 with error type `permission_error`
### Requirement: Channel model restrictions remain enforced
The system SHALL keep existing channel model restriction behavior for image and non-image OpenAI requests, including when the advanced OpenAI account scheduler is enabled.
#### Scenario: Advanced scheduler blocks restricted requested model
- **WHEN** a channel has `restrict_models=true`
- **AND** the requested model is not allowed by channel pricing or mapping rules
- **AND** the OpenAI advanced scheduler path is used
- **THEN** the request is rejected before upstream account selection succeeds
#### Scenario: Image generation flag does not bypass channel restrictions
- **WHEN** a group has `allow_image_generation=true`
- **AND** the channel restriction rejects the requested or billing model
- **THEN** the image generation request is rejected
- **AND** no upstream image request is sent