6.7 KiB

1. Data Model And Migration

  • 1.1 Add allow_image_generation, image_rate_independent, and image_rate_multiplier to backend/ent/schema/group.go.
  • 1.2 Create a new idempotent SQL migration after 133_affiliate_rebate_freeze.sql for the three group columns.
  • 1.3 Backfill existing openai, gemini, and antigravity groups to allow_image_generation=true and anthropic groups to false.
  • 1.4 Backfill all existing groups to image_rate_independent=false and image_rate_multiplier=1 without changing existing image_price_1k/2k/4k.
  • 1.5 Regenerate or update Ent generated group fields, predicates, create/update setters, and query projections.
  • 1.6 Add the new fields to backend group domain/service structs, admin create/update inputs, admin responses, and group serialization.

2. Admin API And Frontend

  • 2.1 Add allow_image_generation, image_rate_independent, and image_rate_multiplier to CreateGroupRequest and UpdateGroupRequest.
  • 2.2 Validate image_rate_multiplier >= 0 and keep negative image prices using the existing clear-price behavior only for image_price_*.
  • 2.3 Add the new fields to frontend/src/types/index.ts group, create, and update interfaces.
  • 2.4 Ensure omitted update fields do not overwrite existing image generation and multiplier mode settings.
  • 2.5 Update frontend/src/views/admin/GroupsView.vue create/edit forms with a 生图开关, 生图倍率是否独立开关, and conditional image multiplier input.
  • 2.6 Add a live final-price preview for image_price_1k/2k/4k under shared and independent multiplier modes.
  • 2.7 Update group form help text to state that default image billing shares the existing group effective multiplier and independent mode uses the image multiplier input.
  • 2.8 Update i18n strings for the new controls and image multiplier mode explanation.

3. Image Generation Access Control

  • 3.1 Implement a shared helper that detects image generation intent from endpoint, requested model, tools[], and tool_choice.
  • 3.2 Gate /v1/images/generations and /v1/images/edits in backend/internal/handler/openai_images.go after request parsing and before billing eligibility/account scheduling.
  • 3.3 Gate /v1/responses explicit image_generation tool requests in backend/internal/service/openai_gateway_service.go before upstream account scheduling.
  • 3.4 Prevent normalizeOpenAIResponsesImageOnlyModel from rewriting gpt-image-* Responses requests when the group does not allow image generation.
  • 3.5 Skip Codex image_generation auto-injection and image bridge instructions when the group does not allow image generation.
  • 3.6 Re-run image intent detection after service-side request mutation and before upstream dispatch.
  • 3.7 Ensure OpenAI advanced scheduler paths apply the same channel RestrictModels checks as the load-aware path.

4. Responses Image Output Accounting

  • 4.1 Add shared parsers for final image_generation_call.result outputs in non-stream JSON and SSE payloads.
  • 4.2 Extend openaiStreamingResult with image count, image size tier, and image billing model fields.
  • 4.3 Update handleStreamingResponse to count final image outputs while preserving existing stream forwarding and usage parsing.
  • 4.4 Update handleStreamingResponsePassthrough with the same image output counting.
  • 4.5 Update handleNonStreamingResponse to count final image outputs from output[].
  • 4.6 Update handleNonStreamingResponsePassthrough with the same non-stream image output counting.
  • 4.7 Populate OpenAIForwardResult.ImageCount, ImageSize, and image billing model for gpt-5.4 / gpt-5.5 + image_generation requests.

5. Images API Accounting And Size Tiers

  • 5.1 Extend OpenAI Images API-key stream counting to handle image_generation.completed, response.output_item.done, and response.completed.
  • 5.2 Reuse the same final-image de-duplication rules across Images API and Responses API paths.
  • 5.3 Keep unknown explicit OpenAI image sizes pass-through and delegate invalid-size errors to upstream.
  • 5.4 Map documented OpenAI image sizes to 1K/2K/4K billing tiers without rewriting request parameters.
  • 5.5 Classify custom OpenAI WIDTHxHEIGHT sizes by 2560x1440 total-pixel boundary, falling back to 2K when unparseable.

6. Billing And Usage Logs

  • 6.1 Add an image multiplier resolver: shared mode uses the current effective group multiplier, independent mode uses apiKey.Group.ImageRateMultiplier.
  • 6.2 Update CalculateImageCost or its caller contract so image costs use the resolved image multiplier.
  • 6.3 Set image usage log RateMultiplier to the applied image multiplier; keep token logs unchanged.
  • 6.4 Change OpenAI channel image billing RequestCount from 1 to result.ImageCount.
  • 6.5 Change non-OpenAI gateway channel image billing RequestCount from 1 to result.ImageCount.
  • 6.6 Pass actual image count into account stats pricing for billing_mode=image.
  • 6.7 Ensure ImageCount > 0 writes a usage log and bills even when upstream token usage is zero.
  • 6.8 Record accompanying token usage for Responses image tool requests while keeping default billing mode as image.

7. Tests And Documentation

  • 7.1 Add backend tests for disabled group rejecting /v1/images/*, gpt-image-* Responses, explicit image_generation, and image tool_choice.
  • 7.2 Add backend tests proving disabled Codex groups do not receive injected image tools while enabled Codex groups still do.
  • 7.3 Add backend tests proving omitted group update fields preserve existing image generation and multiplier mode settings.
  • 7.4 Add Responses stream and non-stream tests for gpt-5.4 / gpt-5.5 + image_generation image counting and image billing.
  • 7.5 Add Images API stream tests for image_generation.completed, response.output_item.done, and response.completed counting.
  • 7.6 Add billing tests for shared mode rate_multiplier=0.15, image_price_1k=0.2, final actual_cost=0.03.
  • 7.7 Add billing tests for independent mode rate_multiplier=0.15, image_rate_multiplier=1, image_price_1k=0.2, final actual_cost=0.2.
  • 7.8 Add channel image billing tests proving multi-image requests use RequestCount=ImageCount in both shared and independent multiplier modes.
  • 7.9 Add size-tier tests for known OpenAI sizes and unknown explicit size pass-through.
  • 7.10 Add Responses image tool tests proving token usage is recorded but default billing remains image-mode only.
  • 7.11 Update 2ue/image-billing-risk-analysis.md or add a linked follow-up note that points to this OpenSpec change as the normalized solution.