Skip to content

feat(pixel-perfect): expose standalone local tool API - #496

Open
huyanxius wants to merge 9 commits into
1024XEngineer:mainfrom
huyanxius:feat/492-pixel-perfect-api
Open

feat(pixel-perfect): expose standalone local tool API#496
huyanxius wants to merge 9 commits into
1024XEngineer:mainfrom
huyanxius:feat/492-pixel-perfect-api

Conversation

@huyanxius

Copy link
Copy Markdown
Collaborator

新增独立完美像素工具 API,只在这一层组合网格检测器与显式重建器;浏览器直传图片并直接接收 PNG,现有生成管线、媒体服务、数据库和对象存储均不参与。

Why

检测与重建模块需要一个最小的后端调用入口,但这个入口不能扩散进现有生成或工作流系统,也不能让本地 CPU 工具形成无界的上传、子进程或并发资源风险。

Changes

  • 新增认证文件端点 POST /tools/pixel-perfect,支持 PNG/JPEG、自动检测和手动 pixel_size
  • 自动模式按六字段契约调用检测器,再把显式网格传给重建器;手动模式完全绕过检测器。
  • 任一轴 <3px 的自动结果不继续处理,要求调用方提供手动尺寸。
  • 增加 multipart 前置请求体/并发限制、子进程超时和有界 stdout/stderr、稳定错误映射及完整 PNG 校验。
  • 增加双向 import-linter 门禁,禁止工具依赖生成基础设施,也禁止现有生成链路依赖工具。
  • Docker 分阶段构建两个原生模块,运行镜像只复制二进制和 MIT 许可证。

Implementation

  • 业务边界位于 windup_app.server.pixel_perfect;它只依赖 Pillow 与 Python 标准库,不导入 windup_ai_enginewindup_framework、媒体或 orchestrator。
  • ASGI 中间件在 multipart 解析和临时文件落盘前按真实数据流限制 11MiB,并从接收阶段占用工具并发槽。
  • 原生适配器使用 stdin/stdout 协议;输出边读边限,超时、信号或异常退出映射为工具不可用。

Verification

  • Targeted ruff format --checkruff check:通过。
  • pytest -q tests/test_pixel_perfect_api.py --no-cov:20 项通过,0 项失败。
  • lint-imports:4 个架构契约通过,0 个破坏。
  • OpenAPI 重导出与 git diff --check:通过。
  • Combined tree:两个 locked Rust crate 构建通过;真实 PNG/JPEG 的自动与手动 API 共 4 条路径通过。
  • Combined Docker:镜像构建通过;两个二进制与两份许可证存在,不含 cargorustc/app/native/build
  • GitHub Actions:等待远端分支触发。

Scope

Development Context

  • 关键开发约束:三个模块必须独立;API 只负责组合;前端不做;不得对现有生成和后端业务产生破坏或耦合。
  • 人工 Review 说明:合并前请后端负责同学重点确认 ASGI 上传边界、子进程生命周期、Docker combined-tree 结果和三 PR 合入顺序;本 PR 不以本地及独立代码验收代替仓库人工 Review。

Related Issues

Closes #492

Refs #489

The application needs a minimal boundary for local grid detection and reconstruction.

Add immutable result types and stable input, busy, and unavailable error classes.

Later adapters can compose the native modules without importing business services.
The tool API must invoke fixed local binaries without unbounded subprocess resources.

Add six-field detector parsing, explicit reconstructor arguments, output limits, timeouts, and exit classification.

Native failures now map to controlled tool errors instead of leaking process behavior.
Automatic and manual modes need one application boundary that remains outside generation.

Compose detection and explicit reconstruction with finite parameters, bounded concurrency, and PNG validation.

The tool can run independently while rejecting unsupported sub-three-pixel auto results.
Browsers need an explicit endpoint that never touches storage or generation workflows.

Add streamed request limits, local-tool error mapping, PNG metadata headers, and composition-root registration.

The authenticated endpoint now returns the rebuilt image directly with bounded upload concurrency.
The app package inspects upload and reconstruction dimensions at its own boundary.

Declare Pillow directly and update only the corresponding workspace lock metadata.

Runtime dependency ownership no longer relies on the unrelated AI engine package.
The new tool must remain separate from existing generation and infrastructure modules.

Add bidirectional forbidden-import contracts for the tool, orchestrator, generation API, and worker.

Future coupling attempts now fail the existing architecture gate.
Production needs both standalone Rust modules without shipping a Rust runtime or source tree.

Build each locked crate in a separate stage and copy only binaries plus MIT licenses into the image.

The Python runtime can invoke fixed local tools through explicit environment paths.
The explicit API needs regression evidence for composition, resources, and failure mapping.

Cover uploads, manual bypass, sub-three-pixel rejection, native limits, concurrency, CORS, and OpenAPI.

Tool regressions now fail without exercising storage, generation, databases, or external services.
The repository OpenAPI artifact must match the newly registered multipart endpoint.

Export the PNG success response, business-error JSON, form parameters, and validation schema.

Clients and CI now see the same explicit tool contract as the running application.
@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
windup Ignored Ignored Aug 20, 2026 12:52pm

@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review conclusion

The standalone API boundary, subprocess adapter, packaging changes, OpenAPI export, and architecture contracts were reviewed against the fixed SHA range. The targeted 20-test suite, Ruff checks, formatting check, and all four import-linter contracts pass. One integration-level upload-limit path does not preserve the API's documented business-error envelope, as detailed inline.

View job run

if message["type"] == "http.request":
received += len(message.get("body", b""))
if received > self.max_body_bytes:
raise _BodyTooLarge

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 让超限上传走统一业务错误响应

这里从 receive 抛出的 _BodyTooLarge 会被 FastAPI/Starlette 的 multipart 解析器先捕获并转换成框架级 400,因此外层的 except _BodyTooLarge 实际不会执行。用完整应用上传 12 MiB 文件时,响应是 HTTP 400 {'detail':'There was an error parsing the body'},而不是项目约定的 HTTP 200 + code=400 业务包络;这也违背了本端点对资源超限提供稳定 API 错误的契约。请在 multipart 解析器之外完成超限响应或拦截其解析失败结果,并增加一个通过 TestClient 发送超过 11 MiB multipart 的集成测试;当前直接调用中间件的测试无法覆盖这一行为。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(pixel-perfect): expose an independent tool API

1 participant