Skip to content

feat(drivers): add huggingface cloud storage driver - #2799

Open
WUHINS wants to merge 5 commits into
OpenListTeam:mainfrom
WUHINS:main
Open

feat(drivers): add huggingface cloud storage driver#2799
WUHINS wants to merge 5 commits into
OpenListTeam:mainfrom
WUHINS:main

Conversation

@WUHINS

@WUHINS WUHINS commented Jul 16, 2026

Copy link
Copy Markdown

Summary / 摘要

实现了 HuggingFace 仓库作为 OpenList 存储驱动的完整功能。

用户可感知的变化

  • 新增 HuggingFace 驱动类型,支持模型(model) / 数据集(dataset) / 空间(space) 三种仓库
  • 支持配置项:repo_id(必填)、api_tokenref(分支/标签/commit SHA,默认 main)、repo_type(默认 model)、hf_proxy(代理地址)
  • 文件上传:<5MB 走 base64 NDJSON 内联提交,≥5MB 自动切换到 HuggingFace LFS(S3 presigned URL 直传)
  • 支持目录创建(.gitkeep 方式)、文件/目录删除、文件列表、下载直链生成

重要实现变化

  • 新增 5 个文件:drivers/huggingface/driver.go(核心逻辑)、meta.go(驱动元数据)、types.go(API 类型)、util.go(工具函数),以及在 drivers/all.go 注册

  • LFS 上传流程:saveStream 写临时文件 + SHA256 → preupload 检测 → LFS batch API 获取 S3 presigned URL → PUT 直传 S3(支持 fallback 到 POST)→ verify(可选)→ NDJSON commit 提交 lfsFile 引用

  • 小型文件流式提交:io.Pipe + base64 编码 + NDJSON 内嵌,避免写临时文件

  • 自定义 HTTP 客户端:s3Client() 单例共享连接池(5 分钟 ResponseHeaderTimeout),hfClient() 独立客户端(DisableKeepAlives)用于 HF API

  • context.WithoutCancel 保护 S3 上传 body 不被任务取消中断

  • 过滤未签名的 x-amz-* 头部,避免 S3 403(X-Amz-SignedHeaders=host)

  • saveStream 增加 fi.Size() != stream.GetSize() 校验,提前捕获数据不完整

  • This PR has breaking changes.
    / 此 PR 包含破坏性变更。

  • This PR changes public API, config, storage format, or migration behavior.
    / 此 PR 修改了公开 API、配置、存储格式或迁移行为。

  • This PR requires corresponding changes in related repositories.
    / 此 PR 需要关联仓库同步修改。

Related repository PRs / 关联仓库 PR:

  • OpenList-Frontend:
  • OpenList-Docs:

Related Issues / 关联 Issue

Testing / 测试

  • go build -o OpenList.exe . — 编译通过,生成 ~124MB 可执行文件
  • Manual test / 手动测试:
    • 目标驱动上下传(上传小文件、大文件 LFS 自动切换)
    • 文件复制、目录创建、删除操作
    • 代理配置(hf_proxy)验证
    • 使用 Go 1.23+ 构建,全量编译无报错

Checklist / 检查清单

  • I have read CONTRIBUTING.
    / 我已阅读 CONTRIBUTING
  • I confirm this contribution follows the repository license, contribution policy, and code of conduct.
    / 我确认此贡献符合仓库许可证、贡献规范和行为准则。
  • I have formatted the changed code with gofmt, go fmt, or prettier where applicable.
    / 我已按适用情况使用 gofmtgo fmtprettier 格式化变更代码。
  • I have requested review from relevant maintainers or code owners where applicable.
    / 我已在适用情况下请求相关维护者或代码所有者审查。

AI Disclosure / AI 使用声明

  • This PR includes AI-assisted content.
    / 此 PR 包含 AI 辅助内容。

Tools used / 使用工具:

  • ChatGPT
  • Codex
  • GitHub Copilot
  • Claude
  • Gemini
  • Other (please specify) / 其他(请注明): opencode (deepseek-v4-flash-free)

Usage scope / 使用范围:

  • Code generation / 代码生成

  • Refactoring / 重构

  • Documentation / 文档

  • Tests / 测试

  • Translation / 翻译

  • Review assistance / 审查辅助

  • I have reviewed and validated all AI-assisted content included in this PR.
    / 我已审核并验证此 PR 中的所有 AI 辅助内容。

  • I have ensured that all AI-assisted commits include Co-Authored-By attribution.
    / 我已确保所有 AI 辅助提交都包含 Co-Authored-By 归属信息。

  • I can reproduce all AI-assisted content included in this PR without any AI tools.
    / 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。


代码实现思路和驱动编写方向由开发者指导,针对 HF 官方 API,初次尝试编写 OpenList 驱动。如有缺陷请指出。


如果需要我调整措辞或增减内容,直接说。

WUHINS added 2 commits July 16, 2026 23:33
实现了HuggingFace仓库作为存储驱动的完整功能,支持模型/数据集/空间三种仓库类型,支持代理配置、LFS大文件上传、目录创建和删除等操作,同时在drivers/all.go中注册该驱动。
重新导入三个编写过程中因意外丢失的存储驱动
jyxjjj
jyxjjj previously requested changes Jul 16, 2026

@jyxjjj jyxjjj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

临时文件不要提交

清理仓库中不再需要的.tmp/CloudPaste和.tmp/OpenList-Frontend临时子模块
@WUHINS

WUHINS commented Jul 16, 2026

Copy link
Copy Markdown
Author

临时文件不要提交

已改正,感谢提醒

@zjhcx

zjhcx commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

HF仓库已经支持S3访问了,数据集还不支持

@WUHINS

WUHINS commented Jul 17, 2026

Copy link
Copy Markdown
Author

HF仓库已经支持S3访问了,数据集还不支持

所以主要是支持模型和数据集,只是对接API的话顺手做全可能更好,毕竟小白不一定知道HF支持S3,S3配置也有点难度。

@xrgzs xrgzs changed the title feat(huggingface): add huggingface cloud storage driver feat(drivers): add huggingface cloud storage driver Jul 17, 2026
@xrgzs xrgzs added enhancement Module: Driver Driver-Related Issue/PR labels Jul 17, 2026
@WUHINS

WUHINS commented Jul 17, 2026

Copy link
Copy Markdown
Author

HF仓库已经支持S3访问了,数据集还不支持

我看官方说法是桶支持,但标准的模型、数据集几乎不支持
且官方似乎没有明确说明桶是否免费。

@zjhcx

zjhcx commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

HF仓库已经支持S3访问了,数据集还不支持

我看官方说法是桶支持,但标准的模型、数据集几乎不支持 且官方似乎没有明确说明桶是否免费。

确实,不过我试了一下,桶目前是和数据集和模型共享存储空间的

@WUHINS

WUHINS commented Jul 27, 2026

Copy link
Copy Markdown
Author

HF仓库已经支持S3访问了,数据集还不支持

我看官方说法是桶支持,但标准的模型、数据集几乎不支持 且官方似乎没有明确说明桶是否免费。

确实,不过我试了一下,桶目前是和数据集和模型共享存储空间的

当这吃的是私人仓库空间好像,我打算是白嫖公共空间用来挂载AI数据

@xrgzs xrgzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@WUHINS

  1. go fmt 跑一下,代码格式有问题
  2. 自建请求客户端,无适配OpenList Conf代理配置逻辑,建议先检查一下是否真的需要,否则直接用base中的即可。(让AI看一遍internal/net)
  3. 文档弄一下:https://github.com/OpenListTeam/OpenList-Docs

Comment thread drivers/huggingface/driver.go Outdated
return d.lfsUploadAndCommit(ctx, tmp, filePath, fileName, sha256Hex, size, up)
}
return d.streamCommit(ctx, tmp, filePath, fileName, size, up)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

全量落盘,未使用框架的流式缓存工具 internal/stream.CacheFullAndHash,建议整改

Comment on lines +26 to +37
// hfClient is a dedicated HTTP client for HF API requests,
// separate from base.HttpClient to avoid keep-alive connection reuse issues.
func hfClient() *http.Client {
return &http.Client{
Timeout: 30 * time.Minute,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: false},
DisableKeepAlives: true,
MaxIdleConns: 0,
},
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

这个是不是不会走配置文件中的代理?

Comment on lines +297 to +321
// s3Client returns a shared HTTP client for S3 LFS uploads.
func s3Client() *http.Client {
s3HTTPClientOnce.Do(func() {
s3HTTPClient = &http.Client{
Timeout: 30 * time.Minute,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false,
MinVersion: tls.VersionTLS12,
},
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: false,
MaxIdleConns: 2,
MaxIdleConnsPerHost: 2,
IdleConnTimeout: 90 * time.Second,
ResponseHeaderTimeout: 5 * time.Minute,
ExpectContinueTimeout: 5 * time.Second,
},
}
})
return s3HTTPClient
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

这个是不是不会走配置文件中的代理?

@WUHINS

WUHINS commented Aug 1, 2026

Copy link
Copy Markdown
Author

@WUHINS

  1. go fmt 跑一下,代码格式有问题
  2. 自建请求客户端,无适配OpenList Conf代理配置逻辑,建议先检查一下是否真的需要,否则直接用base中的即可。(让AI看一遍internal/net)
  3. 文档弄一下:https://github.com/OpenListTeam/OpenList-Docs

文档已提交 OpenListTeam/OpenList-Docs#351

hfClient() 与 s3Client() 的自定义 Transport 现在都会调用 netutil.SetProxyIfConfigured(transport)(internal/net/util.go 中定义),读取 conf.Conf.ProxyAddress 并设置 transport.Proxy,因此两个客户端都会遵循 OpenList Conf 中配置的代理。

关于"是否真的需要自定义客户端,还是直接复用 base 中的":我们排查了 internal/net 和 drivers/base/client.go,结论是这两个客户端有必要保留,理由如下:

base.HttpClient(即 net.NewHttpClient())默认带 DisableKeepAlives=false、开启 HTTP/2,且无 S3 上传所需的连接参数定制;
hfClient 需要 DisableKeepAlives: true 规避 HF Commit API 的 keep-alive 连接复用问题(这是当初拆出自定义 client 的原因);
s3Client 需要 ForceAttemptHTTP2: false、MaxIdleConns、Dialer 超时等针对 HF LFS 后端 S3 上传的调优,base.HttpClient 无法覆盖这些场景
因此保留自建客户端是合理的,现在也已补上代理适配。

@WUHINS
WUHINS requested review from jyxjjj and xrgzs August 1, 2026 13:28
@WUHINS

WUHINS commented Aug 1, 2026

Copy link
Copy Markdown
Author

感谢 review,三条意见都已在提交 752f237 中处理完毕:

  1. 全量落盘,未使用框架的流式缓存工具 —— 已修复。Put() 现在使用 stream.CacheFullAndHash(file, &up, utils.SHA256),返回缓存文件及 SHA-256 十六进制哈希。原先的 saveStream() 辅助函数、os.CreateTemp、os.Remove、手动 sha256.New() 逻辑均已移除。streamCommit、lfsUploadAndCommit、streamUpload、streamUploadPost、doCommitLFS 现在统一接收 model.File 缓存,通过框架的混合流式缓存读取,不再将整个临时文件写入磁盘。

  2. 自定义 HTTP client 未适配 OpenList Conf 代理配置 —— 已修复。hfClient() 与 s3Client() 现在都调用 netutil.SetProxyIfConfigured(transport)(定义于 internal/net/util.go),读取 conf.Conf.ProxyAddress 并设置 transport.Proxy,两个客户端都会遵循 OpenList 中配置的代理。

关于"是否真的需要自定义客户端、能否直接复用 base.HttpClient":排查 internal/net 与 drivers/base/client.go 后,结论是保留自定义客户端是合理的:

base.HttpClient(即 net.NewHttpClient())不提供 DisableKeepAlives、禁用 HTTP/2、以及面向 S3 上传的连接参数定制;
hfClient 需要 DisableKeepAlives: true 规避 HF Commit API 的 keep-alive 连接复用问题(当初拆分独立 client 的原因);
s3Client 需要 ForceAttemptHTTP2: false、MaxIdleConns 以及针对 HF LFS 后端(S3)上传定制的 Dialer 超时,base.HttpClient 无法覆盖。
因此保留自建客户端,并已补充代理适配。

  1. gofmt 代码格式 —— 已修复。gofmt -l drivers/huggingface/ 现在无任何输出;types.go 的结构体字段对齐、util.go 的 import 顺序均已修正。

  2. 文档 —— 已在 OpenList-Docs 仓库新增 pages/guide/drivers/huggingface.md,中英双语覆盖 仓库 ID、API Token、引用(Ref)、仓库类型、HF Proxy、根目录路径、上传说明 及 默认下载方式流程图

@PIKACHUIM PIKACHUIM left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🙏 感谢贡献

感谢 @WUHINS 提交此PR!我已完成代码评审,以下是评审结果。


🤖 AI 自动审核声明

本评审报告由 AI 自动生成,当前使用 Claude Opus 5 模型进行分析,部分复杂场景可能辅助使用 ChatGPT、DeepSeek 等模型进行交叉验证。

⚠️ AI 分析结果仅供参考,可能存在误判或遗漏。如您发现任何问题或有不同意见,欢迎随时提出讨论和纠正。

⚠️ 重要提醒:即使 AI 评审认为代码质量良好且建议合并,最终是否合并仍需由项目维护者进行人工判定。项目维护者会综合考虑代码质量、项目规划、技术方向、团队资源等多方面因素做出决策。


📖 PR背景与需求

PR标题:feat(drivers): add huggingface cloud storage driver

关联Issue:无

需求说明:实现 HuggingFace 仓库作为 OpenList 存储驱动的完整功能,支持模型(model) / 数据集(dataset) / 空间(space) 三种仓库类型。文件上传时,小于 5MB 的文件走 base64 NDJSON 内联提交,大于等于 5MB 的文件自动切换到 HuggingFace LFS(S3 presigned URL 直传)。

预期目标:用户可以将 HuggingFace 仓库作为 OpenList 的存储后端,支持文件上传、下载、列表、删除、目录创建等完整功能,并支持代理配置。


📋 问题摘要

  • 功能性:功能设计完整,实现了 HuggingFace 存储驱动的核心功能
  • ⚠️ 安全性:需要加强错误处理和资源管理
  • 💡 代码质量:实现较为完整,但有多处可优化点

📂 逐文件分析

drivers/huggingface/driver.go

改动意图:实现 HuggingFace 驱动的核心逻辑,包括文件上传(小文件 base64 内联提交、大文件 LFS 上传)、文件列表、下载链接生成、目录创建、文件删除等功能。

代码修改逻辑

  • LFS 上传流程Put()stream.CacheFullAndHash() 计算 SHA256 → preupload() 检测 → LFS batch API 获取 S3 presigned URL → streamUpload() PUT 直传 S3(支持 fallback 到 POST)→ verify(可选)→ doCommitLFS() NDJSON commit 提交 lfsFile 引用
  • 小型文件流式提交streamCommit() 使用 io.Pipe + base64 编码 + NDJSON 内嵌,避免写临时文件
  • 自定义 HTTP 客户端s3Client() 单例共享连接池(5 分钟 ResponseHeaderTimeout),hfClient() 独立客户端(DisableKeepAlives)用于 HF API
  • context.WithoutCancel 保护 S3 上传 body 不被任务取消中断
  • 过滤未签名的 x-amz-* 头部,避免 S3 403(X-Amz-SignedHeaders=host)

合理性评估

  • 优点

    • 完整实现了 HuggingFace 存储驱动的核心功能
    • LFS 上传流程设计合理,支持 S3 presigned URL 直传
    • 使用 context.WithoutCancel 保护 S3 上传不被中断
    • 过滤未签名的 x-amz-* 头部,避免 S3 签名错误
    • 小文件流式提交避免写临时文件,节省磁盘空间
  • ⚠️ 问题

    1. 资源泄漏风险streamCommit() 中的 io.Pipe 在 goroutine 中写入,如果写入失败或 cache.Seek() 失败,pw.CloseWithError(err) 会正确关闭,但如果后续 HTTP 请求构建失败(http.NewRequestWithContext() 返回错误),goroutine 可能仍在写入,导致 pr 未被消费完。建议在 HTTP 请求构建失败时也关闭 pr

    2. 错误处理不完整lfsUploadAndCommit() 中,如果 obj.Actions 为 nil 或没有 "upload" action,会直接调用 doCommitLFS(),但此时文件内容可能还未上传到 LFS,这可能导致提交失败或文件内容丢失。建议增加明确的错误检查。

    3. hfClient() DisableKeepAlives:设置 DisableKeepAlives: true 会导致每次请求都创建新连接,对于频繁的 HF API 调用(如列表、下载等)会降低性能。建议保留 KeepAlive,仅在特定场景(如 S3 上传)使用独立客户端。

    4. 缺少超时配置s3Client() 设置了 ResponseHeaderTimeout: 5 * time.Minute,但 hfClient() 设置了 Timeout: 30 * time.Minute,这对于列表等快速操作来说过长。建议根据操作类型设置不同的超时时间。

    5. 缺少重试机制:对于网络操作(如 S3 上传、LFS batch API 调用),建议增加重试机制,提高上传成功率。

详细建议

  1. 修复 streamCommit() 资源泄漏风险

    func (d *HuggingFace) streamCommit(ctx context.Context, cache model.File, filePath, fileName string, size int64, up driver.UpdateProgress) error {
        headerLine := fmt.Sprintf(`{"key":"header","value":{"summary":"Upload %s"}}`, fileName) + "\n"
        filePrefix := fmt.Sprintf(`{"key":"file","value":{"path":"%s","content":"`, filePath)
        fileSuffix := `","encoding":"base64"}}` + "\n"
    
        b64Len := calculateBase64Length(size)
        contentLength := int64(len(headerLine)+len(filePrefix)) + b64Len + int64(len(fileSuffix))
    
        pr, pw := io.Pipe()
        errChan := make(chan error, 1)
        go func() {
            defer pw.Close()
            if _, err := cache.Seek(0, io.SeekStart); err != nil {
                errChan <- err
                _ = pw.CloseWithError(err)
                return
            }
            encoder := base64.NewEncoder(base64.StdEncoding, pw)
            if _, err := io.Copy(encoder, cache); err != nil {
                errChan <- err
                _ = pw.CloseWithError(err)
                return
            }
            _ = encoder.Close()
            errChan <- nil
        }()
    
        body := io.MultiReader(
            strings.NewReader(headerLine),
            strings.NewReader(filePrefix),
            pr,
            strings.NewReader(fileSuffix),
        )
    
        req, err := http.NewRequestWithContext(ctx, http.MethodPost,
            d.apiURL(fmt.Sprintf("/commit/%s", d.Ref)),
            driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
                Reader:         &driver.SimpleReaderWithSize{Reader: body, Size: contentLength},
                UpdateProgress: up,
            }))
        if err != nil {
            pr.Close() // 确保关闭 reader
            return fmt.Errorf("stream commit request build: %w", err)
        }
        
        // ... 继续后续逻辑
    }
  2. 增强 lfsUploadAndCommit() 错误检查

    obj := batchResp.Objects[0]
    if obj.Error != nil {
        return fmt.Errorf("lfs batch error: %v", obj.Error)
    }
    if obj.Actions == nil {
        // 文件已存在于 LFS,直接提交引用
        return d.doCommitLFS(ctx, filePath, sha256Hex, size)
    }
    uploadAction, ok := obj.Actions["upload"]
    if !ok {
        // 没有 upload action,可能文件已存在
        return d.doCommitLFS(ctx, filePath, sha256Hex, size)
    }
  3. 优化 hfClient() 连接管理

    func hfClient() *http.Client {
        transport := &http.Transport{
            TLSClientConfig:       &tls.Config{InsecureSkipVerify: false},
            DisableKeepAlives:     false, // 保留 KeepAlive 提高性能
            MaxIdleConns:          10,
            MaxIdleConnsPerHost:   2,
            IdleConnTimeout:       90 * time.Second,
            ResponseHeaderTimeout: 30 * time.Second,
        }
        netutil.SetProxyIfConfigured(transport)
        return &http.Client{
            Timeout:   60 * time.Second, // 减少超时时间
            Transport: transport,
        }
    }
  4. 缺少单元测试:建议补充单元测试覆盖核心功能(文件上传、列表、删除等)。


drivers/huggingface/meta.go

改动意图:定义 HuggingFace 驱动的元数据和配置项。

代码修改逻辑

  • 定义 Addition 结构体,包含 ApiTokenRepoIDRefRepoTypeHFProxy 等配置项
  • 定义 config 变量,设置驱动名称、本地排序、默认根路径

合理性评估

  • 优点

    • 配置项定义清晰,help 标签提供了使用说明
    • 支持可选的 API token,兼容公开仓库
    • 支持代理配置,方便国内用户使用
  • 💡 建议

    • RepoType 的 help 标签可以补充更多说明(如 "model 用于模型仓库,dataset 用于数据集,space 用于应用空间")

drivers/huggingface/types.go

改动意图:定义 HuggingFace API 的请求和响应类型。

代码修改逻辑

  • 定义 TreeEntryErrorResponsePreuploadFilePreuploadResponseLFSBatchRequestLFSBatchResponse 等类型

合理性评估

  • 优点

    • 类型定义完整,覆盖了 HuggingFace API 的主要数据结构
    • TreeEntry.toModelObj() 正确处理了目录的 size(设置为 0)
  • ⚠️ 问题

    • TreeEntry 没有 Modified 字段,导致所有文件的修改时间都是 Unix 纪元(1970-01-01)。建议检查 HuggingFace API 是否提供修改时间字段,如果有则解析;如果没有则在注释中说明。

drivers/huggingface/util.go

改动意图:提供工具函数,包括 API URL 构建、错误处理、路径处理等。

代码修改逻辑

  • apiURL()resolveURL()apiRepoType() 等函数用于构建 API 请求 URL
  • toHFError() 将 HTTP 响应转换为错误信息
  • relativePath() 处理路径标准化
  • lastIndexByte() 查找最后一个字节的位置

合理性评估

  • 优点

    • 工具函数设计合理,提高了代码复用性
    • toHFError() 正确解析了 HuggingFace API 的错误响应
  • 💡 建议

    • lastIndexByte() 可以使用标准库的 strings.LastIndexByte() 替代,减少自定义实现

🎯 总体评价

功能性:⭐⭐⭐⭐ - 功能设计完整,实现了 HuggingFace 存储驱动的核心功能
安全性:⭐⭐⭐ - 需要加强错误处理和资源管理,避免资源泄漏
代码质量:⭐⭐⭐ - 实现较为完整,但有多处可优化点,缺少单元测试
实现方案:⭐⭐⭐⭐ - 实现方案合理,LFS 上传流程设计正确

建议操作

  • ✅ Approve(建议合并)
  • 🔄 Request Changes(需要修改)
  • ❌ Close(建议关闭)

理由:此 PR 功能完整、实现合理,但存在以下需要修改的问题:

  1. P1(必须修改)streamCommit() 中的 io.Pipe 资源泄漏风险
  2. P1(必须修改)lfsUploadAndCommit() 中缺少错误检查,可能导致文件上传失败
  3. P2(建议修改):优化 hfClient() 连接管理,提高性能
  4. P2(建议修改):补充单元测试覆盖核心功能

建议先修复 P1 问题后合并,P2 问题可在后续 PR 中优化。


Next Steps / 后续建议

  1. 修复资源泄漏风险和错误检查问题(P1)
  2. 补充单元测试,覆盖文件上传、列表、删除等核心功能
  3. 考虑增加重试机制,提高上传成功率
  4. 优化 HTTP 客户端配置,提高性能
  5. 补充文档说明 HuggingFace 驱动的使用方法和限制

再次感谢你的贡献!这是一个很有价值的功能,期待看到修复后的版本。👏

@jyxjjj
jyxjjj dismissed their stale review August 15, 2026 04:17

dismiss outdated

@WUHINS

WUHINS commented Aug 21, 2026

Copy link
Copy Markdown
Author

现在执行修复

前段时间太忙了

1.  在streamCommit请求构建失败时正确关闭进度更新请求
2.  添加LFS批量上传对象错误的处理逻辑
3.  替换原生lastIndexByte为strings标准库实现,移除重复代码
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Module: Driver Driver-Related Issue/PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants