Files
moteva/server
root 2f5291a0f9 feat(image): pass reference images to GPT image model for edits
Server: forward canvas/reference images to the image model so extract,
continue, and edit requests stay faithful to the source product.
- Add ImageRequestOptions.Images and route requests with inputs to the
  /v1/images/edits endpoint, via multipart upload (default) or JSON
  image_url payload, selectable through Agent.Image.InputImageTransport.
- Extract reference URLs from prompt directives, inline @image tokens,
  and chat message image/mask contents; fold them into the idempotency
  key and prepend a reference-fidelity instruction to the prompt.

Frontend:
- Shrink CanvasToast to a compact top pill.
- Paste an internal transparent clipboard node instead of re-uploading
  when it matches the clipboard image.
- Keep agent-project polling alive on stream error while streaming.
2026-07-08 01:19:20 +08:00
..

img-infinite-canvas API

go-zero backend for the Moteva-style infinite canvas MVP.

Features

  • Dashboard data for the Moteva home page
  • Project creation from prompt
  • Project title rename
  • Full canvas project reads
  • Moteva-style generation mock for image/design workflows
  • Canvas layout save
  • Chat history replay
  • DDD layout with domain, application, infrastructure, and generated handler layers
  • sky-valley/pi Go agent adapter with local desktop agent disabled
  • Optional PostgreSQL persistence through pgx/sqlc
  • Optional Redis cache, default memory cache
  • Asynq job queue for generation, OCR, layer merge, and asset cleanup workers
  • Image asset upload URLs for memory, MinIO, AWS S3, Cloudflare R2, and Aliyun OSS

Configuration

Name: img_infinite_canvas-api
Host: 0.0.0.0
Port: 8888
Timeout: 1200000
Storage:
  Driver: postgres
  DataSource: postgres://canvas:canvas@localhost:15432/canvas?sslmode=disable
Cache:
  Driver: redis
  Addr: localhost:16379
  Password: ""
  DB: 0
  TTLSeconds: 300
JobQueue:
  Driver: asynq
  Addr: localhost:16379
  Password: ""
  DB: 0
  Queue: default
  Concurrency: 10
  MaxRetry: 3
  TimeoutSeconds: 900
  ShutdownTimeoutSeconds: 30
Agent:
  Driver: pi
  Text:
    Driver: vision
    Model: gpt-5.4-mini
    TimeoutSeconds: 240
    CacheTTLSeconds: 600
  Planner:
    Driver: vision
    Model: gpt-5.5
    TimeoutSeconds: 240
  Image:
    BaseURL: http://154.21.87.3:8080
    APIKeyEnv: GPT_IMAGE_API_KEY
    InputImageTransport: file
    TimeoutSeconds: 600
ObjectStorage:
  Driver: minio
  Bucket: canvas-assets
  Endpoint: localhost:19000
  Region: us-east-1
  AccessKey: canvas
  SecretKey: canvas-secret
  PublicBase: http://localhost:19000/canvas-assets
  UseSSL: false
  ExpiresIn: 900

Agent.Image.InputImageTransport controls how input/reference images are sent to the image model for edit/image-to-image calls: file uploads image bytes with multipart form data, while url sends images: [{"image_url": "..."}] for gateways that can fetch public URLs directly.

Start local Docker dependencies for debugging:

docker compose -f ../deploy/docker-compose.yml up -d postgres redis minio

Use PostgreSQL, Redis, and MinIO inside Docker Compose. The compose file runs the API and Asynq worker as separate processes:

Storage:
  Driver: postgres
  DataSource: postgres://canvas:canvas@postgres:5432/canvas?sslmode=disable
Cache:
  Driver: redis
  Addr: redis:6379
  TTLSeconds: 300
JobQueue:
  Driver: asynq
  Addr: redis:6379
  Queue: default
  TimeoutSeconds: 900
ObjectStorage:
  Driver: minio
  Bucket: canvas-assets
  Endpoint: minio:9000
  Region: us-east-1
  AccessKey: canvas
  SecretKey: canvas-secret
  PublicBase: http://localhost:19000/canvas-assets
  UseSSL: false

Running

go run . -f etc/config.yaml -mode all
go run . -f etc/config.yaml -mode api
go run . -f etc/config.yaml -mode worker

Testing

go test ./...
go build ./...

Example

curl http://localhost:8888/api/dashboard

curl -X POST http://localhost:8888/api/projects \
  -H "Content-Type: application/json" \
  -d '{"prompt":"为 still day 品牌服装独立站设计官网视觉方向"}'

curl -X PATCH http://localhost:8888/api/projects/<project-id>/title \
  -H "Content-Type: application/json" \
  -d '{"title":"夏季活动主视觉"}'

curl -X POST http://localhost:8888/api/assets/upload-url \
  -H "Content-Type: application/json" \
  -d '{"fileName":"ref.png","contentType":"image/png"}'

Detailed endpoint docs are in API.md.