Skip to content

feat: 会话附件删除接口与图片输入模型兼容投影#712

Closed
wynxing wants to merge 5 commits into
1024XEngineer:mainfrom
wynxing:feat-session-asset-delete-image-projection
Closed

feat: 会话附件删除接口与图片输入模型兼容投影#712
wynxing wants to merge 5 commits into
1024XEngineer:mainfrom
wynxing:feat-session-asset-delete-image-projection

Conversation

@wynxing
Copy link
Copy Markdown
Collaborator

@wynxing wynxing commented Jun 7, 2026

变更内容

会话附件删除(Session Asset Delete)

  • RuntimePort 拆出 SessionAssetPort 独立接口,新增 DeleteSessionAsset 方法
  • Gateway 注册 DELETE /api/session-assets/{sessionID}/{assetID} 端点,多工作区路由和安全 ACL 适配
  • CLI Bridge 实现 DeleteSessionAsset,修复 Save 缺少会话存在性校验、Open 缺少 os.ErrNotExist 映射
  • Web ChatInput 取消上传时调用 deleteSessionAsset 释放服务端资源

图片输入模型兼容投影(Image Projection)

  • Runtime rejectUnsupportedCurrentImageInput:当前模型不支持图片但用户上传了图片则直接拒绝
  • Runtime projectImagesForModelRequest:对历史消息中的图片做投影降级,不支持图片的模型将历史图片替换为占位文本,不修改持久化消息

新会话防自动切换

  • Web useSessionStore 新增 _pendingNewSession 标记,防止创建新会话期间被 fetchSessions 回调自动切换

破坏性变更

  • RuntimePort 移除了 SaveSessionAsset / OpenSessionAsset,拆入独立的 SessionAssetPort 接口。所有 RuntimePort 实现方需适配。

行为变更

  • SaveSessionAsset 新增会话存在性校验:不存在的 sessionID 之前静默创建文件,现在返回 ErrRuntimeResourceNotFound

验证

  • gofmt -w ./cmd ./internal 通过
  • go build ./... 通过
  • go test ./internal/gateway/... ./internal/runtime/... ./internal/cli/... 通过
  • Web 相关测试通过

Closes #711

- 从 RuntimePort 拆出 SessionAssetPort 独立端口,新增 DeleteSessionAsset 方法
- Gateway 注册 DELETE /api/session-assets 端点,多工作区路由和安全 ACL 适配
- CLI Bridge 实现 DeleteSessionAsset,修复 Save 缺少会话存在性校验、Open 缺少 os.ErrNotExist 映射
- Runtime 图片投影:不支持图片的模型对历史图片替换为占位文本,不修改持久化消息
- Runtime 拒绝不支持的当前图片输入,避免上游 400
- Web ChatInput 取消上传时调用 deleteSessionAsset 释放服务端资源
- Web useSessionStore 新增 _pendingNewSession 防止新会话期间自动切换
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Copy link
Copy Markdown
Contributor

@fennoai fennoai Bot left a comment

Choose a reason for hiding this comment

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

发现 2 个需要处理的问题,已以内联评论标出。

验证:尝试运行 go test ./internal/gateway ./internal/contextgo test ./internal/runtime,但当前环境没有 go 命令,无法执行。

未能定位到 diff 行的发现

  • internal/context/builder.go:22: NewConfiguredBuilder 的 source 仍是可选注入,但这里不再跳过 nil。一旦调用方传入 nil(旧测试也覆盖过这个兼容场景),collectPromptSections 会在调用 source.Sections(...) 时直接 panic。请恢复 nil 过滤,或在收集 section 前做保护,避免可选 source 缺失时把 runtime 拉崩。

Comment thread internal/gateway/network_server.go Outdated
}
if !s.isHTTPControlPlaneMethodAllowed(sessionAssetReadMethod) {
s.writeHTTPAccessDenied(writer, sessionAssetReadMethod)
if !s.isHTTPControlPlaneMethodAllowed(sessionAssetDeleteMethod) {
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.

这里把 GET 附件读取的 ACL 检查成了 sessionAssetDeleteMethod,而下面的 DELETE 处理器又检查 sessionAssetReadMethod。这样一来,只允许读取的配置会错误拒绝 GET、却可能放行 DELETE,破坏新删除端点的最小权限边界。建议 GET 使用 sessionAssetReadMethod,DELETE 使用 sessionAssetDeleteMethod,并补一个只允许其中一个方法的测试。

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 7, 2026

wynxing added 2 commits June 7, 2026 08:40
- 修复 handleSessionAssetRead 中 ACL 检查使用了 sessionAssetDeleteMethod 的 bug
- 修复 handleSessionAssetDelete 中 ACL 检查使用了 sessionAssetReadMethod 的 bug
- 为 newStablePromptSources 添加 nil source 过滤,防止 collectPromptSections panic
- 补充 ACL 独立生效测试(read-only 和 delete-only ACL 场景)
- 补充 nil source 和 mixed nil/valid source 测试
- 补充 multi_workspace Delete 不支持 SessionAssetPort 的错误返回测试
- 补充图片投影空消息和混合消息的边界测试
@wynxing
Copy link
Copy Markdown
Collaborator Author

wynxing commented Jun 7, 2026

Review 回复

ACL 方法名互换

已修复(commit ca378b0)。

ACL 方法名确实写反了:handleSessionAssetRead(GET)错误检查了 sessionAssetDeleteMethod,handleSessionAssetDelete(DELETE)错误检查了 sessionAssetReadMethod。

修复内容:

  • handleSessionAssetRead 改为检查 sessionAssetReadMethod
  • handleSessionAssetDelete 改为检查 sessionAssetDeleteMethod
  • 新增 TestNetworkServerSessionAssetACLIndependent 测试,验证 read-only ACL 下 GET 通过但 DELETE 被拒、delete-only ACL 下 DELETE 通过但 GET 被拒

NewConfiguredBuilder nil source 保护

已修复(commit ca378b0)。

在 newStablePromptSources 的循环中添加了 nil source 过滤,防止 collectPromptSections 调用 source.Sections() 时 panic。补充了 nil source 和 mixed nil/valid source 的测试。

wynxing added 2 commits June 7, 2026 09:24
…setPort 方法被提升的测试缺陷

将 recordingPortWithoutSessionAsset 的嵌入类型从 *recordingPort 改为 RuntimePort 接口,
避免 Go 方法提升机制将 SessionAssetPort 的方法也一并提升,导致类型断言永远成功。
TestNetworkServerSessionAssetACLIndependent 直接用 sessionAssetReadMethod/
sessionAssetDeleteMethod(混合大小写)作为 allow map 键,但 IsAllowed 查找时
用 strings.ToLower 归一化,导致键不匹配返回 403。改用 normalizedMethodSet()
构造内层 map,与生产代码 NewStrictControlPlaneACL 保持一致。
@wynxing
Copy link
Copy Markdown
Collaborator Author

wynxing commented Jun 7, 2026

本 PR 存在大量纯空格/格式变更的脏提交,已由干净替代 PR #713 取代。

@wynxing wynxing closed this Jun 7, 2026
@wynxing wynxing reopened this Jun 7, 2026
Copy link
Copy Markdown
Contributor

@fennoai fennoai Bot left a comment

Choose a reason for hiding this comment

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

发现 1 个需要处理的问题,已以内联评论标出。

验证:尝试运行 go test ./internal/gateway ./internal/runtime ./internal/cli,但当前环境没有 go 命令;尝试运行 Web 相关测试时 vitest 返回 Permission denied,因此未能在本环境完成测试执行。

Comment thread web/src/api/gateway.ts
const res = await fetch(
`${this.baseURL}/api/session-assets/${encodeURIComponent(sessionId)}/${encodeURIComponent(assetId)}`,
{
method: 'DELETE',
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.

这里新增了带 Authorization / X-NeoCode-Workspace-Hash 的浏览器 DELETE 请求,但 NetworkServer.withCORS 仍只返回 Access-Control-Allow-Methods: GET, POST, OPTIONS。当前端和网关跨源(例如 Web dev server 访问本地 gateway)时,浏览器会先发 preflight,并因为允许方法里没有 DELETE 而拦截,清理请求到不了新端点。建议把 DELETE 加到 CORS allow methods,并补一个 OPTIONS preflight 覆盖。

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.

支持会话附件删除与图片输入模型兼容降级

1 participant