Initial TrueGrowth source import

This commit is contained in:
2026-07-07 09:36:36 +08:00
commit 3b6781d695
2283 changed files with 691996 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
## Context
The first GPT Image compatibility phase added profile-level image API compatibility and a dedicated official generation schema:
- `openai.image.gpt-generation-json` -> `/images/generations`
- `openai.image.basic-json` -> existing default compatibility adapter
The second phase needs `/images/edits`, but the project still has only one image task surface and one image adapter method. A broad image operation abstraction would be cleaner long-term, but too large for this step.
## Goals / Non-Goals
- Goals:
- Support official GPT Image image-to-image/edit requests.
- Reuse existing `TaskType.IMAGE` queue/history/canvas flows.
- Keep basic Tuzi/OpenAI-compatible behavior unchanged.
- Avoid routing by model ID alone.
- Non-Goals:
- No new task type.
- No new public MCP tool name.
- No full mask drawing UI in this phase.
## Decisions
- Decision: Add an edit request schema instead of a new task type.
The schema is the existing adapter handoff point. It lets the routing layer choose official generation vs official edit while keeping task plumbing stable.
- Decision: Add planner-level schema preference.
The same model/profile can have both generation and edit bindings. Runtime request shape, not model ID, decides which binding is appropriate.
- Decision: Use multipart edit requests for the official GPT Image adapter.
The official `/images/edits` examples use file-style form fields such as `image[]=@...`. The adapter converts the existing canvas data URLs or fetchable image references to `Blob`s, appends them as `image[]`, and lets `fetch` set the multipart boundary.
## Runtime Flow
```text
Image task
-> extract reference images
-> decide preferred schema:
no references -> openai.image.gpt-generation-json
references/mask/edit mode -> openai.image.gpt-edit-form
-> resolve invocation plan with preferred schema
-> resolve adapter from binding
-> gpt-image-adapter sends /images/generations or /images/edits
```
If the preferred edit schema is unavailable, planning falls back to the highest-priority image binding. That preserves Tuzi/basic compatibility.
## Request Fields
Extend `ImageGenerationRequest` with lightweight edit semantics:
```ts
type ImageGenerationMode = 'text_to_image' | 'image_to_image' | 'image_edit';
interface ImageGenerationRequest {
generationMode?: ImageGenerationMode;
referenceImages?: string[];
maskImage?: string;
inputFidelity?: 'high' | 'low';
}
```
Official edit multipart fields:
```text
model=gpt-image-1.5
prompt=...
image[]=@image-1.png
mask=@mask.png
input_fidelity=high
size=1024x1024
```
## Rollback
Switching a profile from `openai-gpt-image` to `tuzi-compatible` or `openai-compatible-basic` returns reference-image requests to the default adapter compatibility path.

View File

@@ -0,0 +1,37 @@
# Change: Add GPT Image edit support
## Why
Official GPT Image editing uses `/images/edits` with a different request contract from text-to-image generation. The first GPT Image compatibility phase intentionally shipped only `/images/generations`; users now need image-to-image/edit support without replacing the existing Tuzi/basic compatibility fallback.
## What Changes
- Add an official GPT Image edit request schema for `/images/edits`.
- Let image invocation planning prefer a request schema when the current request requires edit semantics.
- Extend the image adapter request shape with lightweight edit fields while keeping `TaskType.IMAGE`.
- Extend the GPT Image adapter to build official multipart edit requests from reference images.
- Keep Tuzi/basic GPT Image compatibility on the existing default adapter path.
- Add tests for generation-vs-edit routing, request bodies, and adapter selection.
## Non-Goals
- Do not add `TaskType.IMAGE_EDIT`.
- Do not add a public `edit_image` MCP tool in this change.
- Do not build full mask drawing UI in this change.
- Do not convert all image providers to a common `image.generate` / `image.edit` abstraction.
## Impact
- Affected specs:
- `provider-routing`
- `image-generation`
- Affected code:
- `packages/drawnix/src/services/provider-routing/types.ts`
- `packages/drawnix/src/services/provider-routing/invocation-planner.ts`
- `packages/drawnix/src/services/provider-routing/settings-repository.ts`
- `packages/drawnix/src/services/provider-routing/binding-inference.ts`
- `packages/drawnix/src/services/provider-routing/endpoint-binding-inference.ts`
- `packages/drawnix/src/services/model-adapters/types.ts`
- `packages/drawnix/src/services/model-adapters/context.ts`
- `packages/drawnix/src/services/model-adapters/gpt-image-adapter.ts`
- `packages/drawnix/src/services/generation-api-service.ts`

View File

@@ -0,0 +1,36 @@
## ADDED Requirements
### Requirement: Support Official GPT Image Edit Requests
The system SHALL send official GPT Image edit requests to `/images/edits` when an official GPT Image profile is selected and the image request includes edit inputs.
#### Scenario: Reference-image request uses edit endpoint
- **GIVEN** a provider profile resolves image API compatibility to `openai-gpt-image`
- **AND** the selected model is a GPT Image model
- **AND** the image request includes at least one reference image
- **WHEN** the image task is executed
- **THEN** the GPT Image adapter SHALL send the request to `/images/edits`
- **AND** include input images as multipart `image[]` file fields
- **AND** SHALL NOT include `response_format`
#### Scenario: Text-only request remains generation
- **GIVEN** a provider profile resolves image API compatibility to `openai-gpt-image`
- **AND** the selected model is a GPT Image model
- **AND** the image request has no reference images or edit inputs
- **WHEN** the image task is executed
- **THEN** the GPT Image adapter SHALL send the request to `/images/generations`
### Requirement: Preserve Basic Reference-Image Compatibility
The system SHALL preserve the existing default adapter behavior for reference-image requests when the selected profile resolves to a basic compatibility mode.
#### Scenario: Tuzi reference-image request stays basic
- **GIVEN** a provider profile resolves image API compatibility to `tuzi-compatible`
- **AND** the selected model is a GPT Image model
- **AND** the request includes reference images
- **WHEN** the image task is executed
- **THEN** the request SHALL remain eligible for the default adapter
- **AND** SHALL NOT require the official GPT Image edit schema

View File

@@ -0,0 +1,30 @@
## ADDED Requirements
### Requirement: Prefer Image Request Schema Per Invocation
The system SHALL allow an image invocation to prefer a request schema when multiple bindings exist for the same provider profile and model.
#### Scenario: Prefer GPT Image edit schema
- **GIVEN** a provider profile exposes both `openai.image.gpt-generation-json` and `openai.image.gpt-edit-form` for the same GPT Image model
- **WHEN** the invocation asks for preferred request schema `openai.image.gpt-edit-form`
- **THEN** the invocation plan SHALL select the edit binding
#### Scenario: Fall back when preferred schema is unavailable
- **GIVEN** a provider profile has only `openai.image.basic-json` for a GPT Image model
- **WHEN** the invocation asks for preferred request schema `openai.image.gpt-edit-form`
- **THEN** the invocation plan SHALL fall back to the available basic binding
### Requirement: Add Official GPT Image Edit Binding
The system SHALL infer an official GPT Image edit binding for provider profiles that resolve to official GPT Image compatibility.
#### Scenario: Official GPT Image profile exposes edit binding
- **GIVEN** a provider profile resolves image API compatibility to `openai-gpt-image`
- **AND** the selected model is a GPT Image model
- **WHEN** image bindings are inferred
- **THEN** one binding SHALL use request schema `openai.image.gpt-edit-form`
- **AND** submit path `/images/edits`
- **AND** protocol `openai.images.edits`

View File

@@ -0,0 +1,33 @@
## 1. Routing And Planning
- [x] 1.1 Add `openai.images.edits` protocol support.
- [x] 1.2 Add `openai.image.gpt-edit-form` binding inference for official GPT Image profiles.
- [x] 1.3 Add planner schema preference support.
- [x] 1.4 Keep basic compatibility profiles on `openai.image.basic-json`.
## 2. Adapter Request Model
- [x] 2.1 Add image generation mode and edit-specific request fields.
- [x] 2.2 Extend GPT Image adapter to build `/images/edits` multipart form bodies.
- [x] 2.3 Parse edit responses through the existing GPT Image response parser.
- [x] 2.4 Keep `/images/generations` behavior unchanged.
## 3. Execution Flow
- [x] 3.1 Detect reference-image/edit requests in `GenerationAPIService`.
- [x] 3.2 Prefer `openai.image.gpt-edit-form` for official GPT profiles when edit inputs are present.
- [x] 3.3 Fall back to existing binding selection when edit schema is unavailable.
## 4. Tests
- [x] 4.1 Add routing tests for generation and edit bindings on the same GPT Image model.
- [x] 4.2 Add planner tests for preferred request schema selection and fallback.
- [x] 4.3 Add GPT adapter edit form body tests.
- [x] 4.4 Add execution/adapter-selection tests for reference-image requests.
- [x] 4.5 Add regression coverage proving Tuzi/basic reference-image requests stay on default adapter.
## 5. Verification
- [x] 5.1 Run targeted Vitest tests.
- [x] 5.2 Run formatting/diff checks.
- [x] 5.3 Attempt TypeScript/OpenSpec validation and document unrelated blockers.