调整素材切分边界像素上限
将视觉绑定区域每条边的调整上限改为固定 32px。 同步 UI 编辑器自动切分技术方案与项目决策记录。 更新边界测试以覆盖绝对像素限制。
This commit is contained in:
@@ -2,11 +2,10 @@ use super::model::BindingArea;
|
||||
use image::RgbaImage;
|
||||
use std::time::Instant;
|
||||
|
||||
/// Each edge may move by at most this percentage of the corresponding area
|
||||
/// dimension returned by the visual model. Keep this policy explicit so
|
||||
/// changing it is an intentional workflow decision rather than a scattered
|
||||
/// numeric literal.
|
||||
pub(crate) const MAX_BINDING_AREA_EDGE_ADJUSTMENT_PERCENT: u32 = 100;
|
||||
/// Each edge may move by at most this many pixels from the area returned by
|
||||
/// the visual model. Keep this policy explicit so changing it is an
|
||||
/// intentional workflow decision rather than a scattered numeric literal.
|
||||
pub(crate) const MAX_BINDING_AREA_EDGE_ADJUSTMENT_PX: u32 = 32;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub(crate) struct NormalizedBindingArea {
|
||||
@@ -87,11 +86,6 @@ fn rect_has_visible_pixel(image: &RgbaImage, rect: Rect) -> bool {
|
||||
(rect.top..rect.bottom).any(|y| (rect.left..rect.right).any(|x| image.get_pixel(x, y).0[3] > 0))
|
||||
}
|
||||
|
||||
fn max_edge_adjustment(dimension: u32) -> u32 {
|
||||
((u64::from(dimension) * u64::from(MAX_BINDING_AREA_EDGE_ADJUSTMENT_PERCENT)) / 100)
|
||||
.min(u64::from(u32::MAX)) as u32
|
||||
}
|
||||
|
||||
fn edge_direction(image: &RgbaImage, rect: Rect, edge: Edge) -> EdgeDirection {
|
||||
if edge_has_visible_pixel(image, rect, edge) {
|
||||
EdgeDirection::Outward
|
||||
@@ -126,15 +120,12 @@ fn edge_displacement(original: Rect, current: Rect, edge: Edge) -> u32 {
|
||||
edge_coordinate(original, edge).abs_diff(edge_coordinate(current, edge))
|
||||
}
|
||||
|
||||
fn edge_adjustment_limit(original: Rect, edge: Edge) -> u32 {
|
||||
max_edge_adjustment(match edge {
|
||||
Edge::Left | Edge::Right => original.right - original.left,
|
||||
Edge::Top | Edge::Bottom => original.bottom - original.top,
|
||||
})
|
||||
fn edge_adjustment_limit() -> u32 {
|
||||
MAX_BINDING_AREA_EDGE_ADJUSTMENT_PX
|
||||
}
|
||||
|
||||
fn reached_adjustment_limit(original: Rect, current: Rect, edge: Edge) -> bool {
|
||||
edge_displacement(original, current, edge) >= edge_adjustment_limit(original, edge)
|
||||
edge_displacement(original, current, edge) >= edge_adjustment_limit()
|
||||
}
|
||||
|
||||
fn can_move_geometrically(
|
||||
@@ -393,10 +384,10 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn caps_each_edge_at_original_dimension() {
|
||||
let image = image_with_rect(64, 64, 0, 0, 64, 64);
|
||||
let result = normalize_binding_area(&image, area(16, 16, 8, 8)).unwrap();
|
||||
assert_eq!(result.area, area(8, 8, 24, 24));
|
||||
fn caps_each_edge_at_absolute_pixel_limit() {
|
||||
let image = image_with_rect(128, 128, 0, 0, 128, 128);
|
||||
let result = normalize_binding_area(&image, area(48, 48, 8, 8)).unwrap();
|
||||
assert_eq!(result.area, area(16, 16, 72, 72));
|
||||
assert!(result.clamped);
|
||||
}
|
||||
|
||||
|
||||
@@ -8040,6 +8040,10 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- `validater(&T) -> Result<(), String>` 只负责业务校验。网络、模型、tool 缺失、JSON 或反序列化错误只按原 history 重试;只有业务校验失败才把序列化后的响应和校验错误合并为一条 system message 追加到 history。
|
||||
- history 仅存在本次请求内存中,不重复图片、不截断、不扩展 `platform-llm` 消息协议;重试次数参数统一使用 `max_retries`。
|
||||
|
||||
## 2026-09-11 UI 编辑器素材切分边界使用固定像素上限
|
||||
|
||||
- UI 编辑器自动切分在 cut 前对视觉模型返回的 `BindingArea` 做像素边界归一化时,每条边相对原始区域最多移动 `32px`,不再按原始区域宽高的百分比计算;Rust 常量为 `MAX_BINDING_AREA_EDGE_ADJUSTMENT_PX`,技术方案同步记录该固定上限。
|
||||
|
||||
## 2026-08-29 DirectProject 受控联网搜索默认与边界
|
||||
|
||||
- 正式产品本次只覆盖 `DirectProject` 单 Codex Agent。`Provider`、`ToolHost`、`DirectHome` 不是 Agent,也不是本次联网主链路;不新增全路由联网或工具桥。唯一受控联网工具为 `agc_tools.agc_web_search`,链路固定为 Codex MCP 工具目录 -> 客户端 loopback `DirectToolBridge` -> 有界 Bing RSS HTTPS -> 过滤 / 脱敏 -> MCP 结果回传。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# UI 编辑器自动切分素材工作流
|
||||
|
||||
更新时间:`2026-09-08`
|
||||
更新时间:`2026-09-11`
|
||||
|
||||
## 目标
|
||||
|
||||
@@ -51,7 +51,7 @@ Rust 在接收并校验工具结果后,才把这两个枚举变体映射为正
|
||||
`spawn_blocking` 任务;image-edit 与 visual binding 网络请求仍运行在 async future 中。
|
||||
- 视觉 binding 输入源图与处理图,必须为当前 batch 每个节点恰好返回一次 `Ok` 或 `NeedRework`。
|
||||
- `Ok` 返回 `NodeId + BindingArea`;Rust 仅校验 NodeId、区域边界和非零尺寸,不检查与原节点框的偏差,也不要求区域不重叠。
|
||||
- cut 前会对视觉模型返回的 `BindingArea` 做本地像素边界归一化。处理图是透明 PNG,有效像素定义为 `alpha > 0`。四条边以模型 area 为起点,每条边根据首次扫描结果固定方向:边上无有效像素则只向内收缩,边上有有效像素则只向外扩展;四边每轮从同一矩形快照同时逐像素推进,直到达到“内侧有像素、外侧无像素”的分界、图像边界或每条边相对原始 area 的位移上限。该上限由模块级常量 `MAX_BINDING_AREA_EDGE_ADJUSTMENT_PERCENT` 定义。方向固定用于避免稀疏像素造成边界来回振荡;没有理想分界时使用受限范围内的最终 area,不重新请求视觉模型,也不转 problematic。全透明处理图不走特殊错误分支,仍沿同一规则得到最终 area 后裁切。归一化只影响本地 cut,不改写原始 `BindingDecision`、sidecar 或 DTO;日志记录原始 area、最终 area、是否变更,以及仍需移动时是否受到该常量上限、图像边界或非零尺寸约束。性能优化列 TODO。
|
||||
- cut 前会对视觉模型返回的 `BindingArea` 做本地像素边界归一化。处理图是透明 PNG,有效像素定义为 `alpha > 0`。四条边以模型 area 为起点,每条边根据首次扫描结果固定方向:边上无有效像素则只向内收缩,边上有有效像素则只向外扩展;四边每轮从同一矩形快照同时逐像素推进,直到达到“内侧有像素、外侧无像素”的分界、图像边界或每条边相对原始 area 的位移上限。每条边最多相对原始 area 移动 `32px`,由模块级常量 `MAX_BINDING_AREA_EDGE_ADJUSTMENT_PX` 定义,与原始 area 尺寸无关。方向固定用于避免稀疏像素造成边界来回振荡;没有理想分界时使用受限范围内的最终 area,不重新请求视觉模型,也不转 problematic。全透明处理图不走特殊错误分支,仍沿同一规则得到最终 area 后裁切。归一化只影响本地 cut,不改写原始 `BindingDecision`、sidecar 或 DTO;日志记录原始 area、最终 area、是否变更,以及仍需移动时是否受到该常量上限、图像边界或非零尺寸约束。性能优化列 TODO。
|
||||
- `NeedRework` 携带短问题描述(最多 512 个 Unicode 字符);通过校验后按产生顺序追加到目标 `SeparationNode.note.rework_notes`,下一次该节点进入 image-edit 时全部意见会注入提取 prompt。结构化工具调用失败时使用可复用 repair harness,把错误反馈给模型并额外请求一次;image-edit 不使用该 harness。
|
||||
- 达到返工上限时仍先保留最后一条视觉模型意见,再把节点追加到 problematic;网络、IO、裁切等基础设施错误不写入节点意见。
|
||||
- 达到模块级重做常量后,节点移入 problematic;不中断整条工作流,最终统一通知用户。image-edit、图像写入或裁切失败保留当前 state 并返回错误,不自动把整批标记为 problematic。
|
||||
|
||||
Reference in New Issue
Block a user