Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add Deepl support for plugins/ai-proxy #1147

Merged
merged 9 commits into from
Aug 15, 2024
Merged

Conversation

urlyy
Copy link
Contributor

@urlyy urlyy commented Jul 23, 2024

Ⅰ. Describe what this PR did

Add Deepl support for plugins/ai-proxy

Ⅱ. Does this pull request fix one issue?

#963

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

  1. ai-proxy/docker-compose.yaml
version: '3.7'
services:
  envoy:
    image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/gateway:v1.4.0-rc.1
    entrypoint: /usr/local/bin/envoy
    # 注意这里对wasm开启了debug级别日志,正式部署时则默认info级别
    command: -c /etc/envoy/envoy.yaml --component-log-level wasm:debug
    depends_on:
    - httpbin
    networks:
    - wasmtest
    ports:
    - "10000:10000"
    volumes:
    - ./envoy.yaml:/etc/envoy/envoy.yaml
    - ./plugin.wasm:/etc/envoy/plugin.wasm

  httpbin:
    image: kennethreitz/httpbin:latest
    networks:
    - wasmtest
    ports:
    - "12345:80"

networks:
  wasmtest: {}
  1. ai-proxy/envoy.yaml
admin:
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 10000
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                scheme_header_transformation:
                  scheme_to_overwrite: https
                stat_prefix: ingress_http
                # Output envoy logs to stdout
                access_log:
                  - name: envoy.access_loggers.stdout
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
                # Modify as required
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains: [ "*" ]
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: deepl
                            timeout: 300s
                http_filters:
                  - name: wasmtest
                    typed_config:
                      "@type": type.googleapis.com/udpa.type.v1.TypedStruct
                      type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
                      value:
                        config:
                          name: wasmtest
                          vm_config:
                            runtime: envoy.wasm.runtime.v8
                            code:
                              local:
                                filename: /etc/envoy/plugin.wasm
                          configuration:
                            "@type": "type.googleapis.com/google.protobuf.StringValue"
                            value: |
                              {
                               "provider": {
                                 "type": "deepl",
                                 "apiTokens": [
                                    "Your DeepL API Key"
                                  ],
                                  "targetLang":"ZH"
                               }
                              }
                  - name: envoy.filters.http.router
  clusters:
    - name: httpbin
      connect_timeout: 30s
      type: LOGICAL_DNS
      # Comment out the following line to test on v6 networks
      dns_lookup_family: V4_ONLY
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: httpbin
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: httpbin
                      port_value: 80
    - name: deepl
      connect_timeout: 30s
      type: LOGICAL_DNS
      dns_lookup_family: V4_ONLY
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: deepl
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: api.deepl.com
                      port_value: 443
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
          "sni": "api.deepl.com"
  1. 编写并运行ai-proxy/build.sh
go mod tidy
tinygo build -o plugin.wasm -scheduler=none -target=wasi -gc=custom -tags="custommalloc nottinygc_finalizer" ./main.go
sudo docker compose up
  1. 发送请求

此处model表示deepl的服务类型,必须为"Free"或"Pro",messages[i].content表示deepl的text[i]messages[i].rolesystem时表示deepl的context

curl --location 'http://127.0.0.1:10000/v1/chat/completions' \
--header 'Content-Type:  application/json' \
--data '{
    "model":"Free",
    "messages": [
        {
            "role": "system",
            "content": "money"
        },
        {
            "content": "sit by the bank"
        },
        {
            "content": "a bank in China"
        }
    ]
}'

响应值

此处choices[i].message.name表示deepl的translations[i].detected_source_languagechoices[i].message.content表示deepl的translations[i].textusage不能从响应中拿到,需要调另外的接口获得。

{
  "choices": [
    {
      "index": 0,
      "message": { "name": "EN", "role": "assistant", "content": "坐庄" }
    },
    {
      "index": 1,
      "message": { "name": "EN", "role": "assistant", "content": "中国银行" }
    }
  ],
  "created": 1722747752,
  "model": "Free",
  "object": "chat.completion",
  "usage": {}
}

"stream":true时

data: {
  "choices": [
    {
      "index": 0,
      "delta": { "name": "EN", "role": "assistant", "content": "坐庄" }
    },
    {
      "index": 1,
      "delta": { "name": "EN", "role": "assistant", "content": "中国银行" }
    }
  ],
  "created": 1722747815,
  "model": "Free",
  "object": "chat.completion",
  "usage": {}
}

Ⅴ. Special notes for reviews

  1. 只实现了对于DeepL的文本翻译接口的接入。
  2. 为了做openai协议到deepl协议的转换,字段映射见上方示例。完整的deepl请求协议可以参考 https://developers.deepl.com/docs/v/zh/api-reference/translate/openapi-spec-for-text-translation。
  3. DeepL不支持流式,但我还是为"stream" : true做了兼容,会进入OnStreamingResponseBody中。但发现ai-proxy/main.go中对于响应头的处理是 "先根据响应头判断是否按流式处理,再根据插件的OnResponseHeaders方法修改响应头",为了根据stream字段判断进入哪个处理响应的方法,我将这两个流程的顺序交换了一下。不知道会不会对其他插件造成影响。
  4. DeepL如果请求异常,会通过改变Http响应状态码来表示,同时返回{ message: "error reason" },具体可参考 https://developers.deepl.com/docs/v/zh/best-practices/error-handling 。但似乎因为这样就不会进入onResponseBody,我就不能把他转成OpenAI协议的响应值了。所以这里还有待处理。
  5. 由于我不进行go mod tidy的话,会有依赖"github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"爆红。我把变更后的go.sum也提交上来了,如果不应该更改的话,我会改回去。

本次改动用到了通义灵码辅助编程

image

@cr7258
Copy link
Collaborator

cr7258 commented Jul 30, 2024

@CH3CHO @urlyy
我根据 Deepl 的文档试了一下:https://developers.deepl.com/docs/v/zh/api-reference/translate/openapi-spec-for-text-translation ,里面有个 context 字段,感觉和 AI 沾点边,我的理解是可以写提示词来影响翻译结果。(如果有用的话,可以根据 context 来设置 system prompt)

context
Additional context that can influence a translation but is not translated itself.

但是根据我的测试,我发现不管加不加 context 好像都不影响翻译的结果。如果是这样的话,那么 Deepl 就相当于是一个普通的翻译 API,在我看来就没用兼容 openai 协议的必要了。

# 不加 context
curl -H "Authorization: DeepL-Auth-Key <API KEY>" https://api-free.deepl.com/v2/translate -H "Content-Type:  application/json" -d '
{
        "source_lang": "EN",
        "target_lang": "ZH",
        "text": ["Higress is a next-generation cloud-native gateway built on the core of open-source Istio + Envoy based on Alibaba’s internal Envoy Gateway practice. It realizes the high integration capability of three-in-one traffic gateway + microservice gateway + security gateway, and deeply integrates Dubbo and Nacos , Sentinel and other micro-service technology stacks can help users greatly reduce the cost of gateway deployment and operation and maintenance without compromising capabilities; fully support Ingress and Gateway APIs in terms of standards, and actively embrace the standard API specifications under cloud native; at the same time, Higress The Controller also supports smooth migration of Nginx Ingress, helping users quickly migrate to Higress at zero cost."]
}'


{"translations":[{"detected_source_language":"EN","text":"Higress是基于阿里巴巴内部Envoy网关实践,以开源Istio+Envoy为核心构建的下一代云原生网关。它实现了流量网关+微服务网关+安全网关三位一体的高集成度能力,深度集成了Dubbo和Nacos、Sentinel等微服务技术栈,可以帮助用户在不影响能力的前提下大大降低网关部署和运维成本;在标准方面全面支持Ingress和Gateway API,积极拥抱云原生下的标准API规范;同时,Higress The Controller还支持Nginx Ingress的平滑迁移,帮助用户零成本快速迁移到Higress。"}]}

# 加 context
curl -H "Authorization: DeepL-Auth-Key <API KEY>" https://api-free.deepl.com/v2/translate -H "Content-Type:  application/json" -d '
{
        "source_lang": "EN",
        "target_lang": "ZH",
        "text": ["Higress is a next-generation cloud-native gateway built on the core of open-source Istio + Envoy based on Alibaba’s internal Envoy Gateway practice. It realizes the high integration capability of three-in-one traffic gateway + microservice gateway + security gateway, and deeply integrates Dubbo and Nacos , Sentinel and other micro-service technology stacks can help users greatly reduce the cost of gateway deployment and operation and maintenance without compromising capabilities; fully support Ingress and Gateway APIs in terms of standards, and actively embrace the standard API specifications under cloud native; at the same time, Higress The Controller also supports smooth migration of Nginx Ingress, helping users quickly migrate to Higress at zero cost."],
        "context": "翻译的时候不要逐字翻译,可以意译,使用一些高级的词汇"
}'

{"translations":[{"detected_source_language":"EN","text":"Higress是基于阿里巴巴内部Envoy网关实践,以开源Istio+Envoy为核心构建的下一代云原生网关。它实现了流量网关+微服务网关+安全网关三位一体的高集成度能力,深度集成了Dubbo和Nacos、Sentinel等微服务技术栈,可以帮助用户在不影响能力的前提下大大降低网关部署和运维成本;在标准方面全面支持Ingress和Gateway API,积极拥抱云原生下的标准API规范;同时,Higress The Controller还支持Nginx Ingress的平滑迁移,帮助用户零成本快速迁移到Higress。"}]}%                                                                                                                                                                                     

@urlyy
Copy link
Contributor Author

urlyy commented Jul 30, 2024

@cr7258 看了几篇博客和官方描述,context起到的引导作用没有prompt那么大,只是缩小一下语境、避免一词多义导致翻译错误的情况。

curl -X POST 'https://api-free.deepl.com/v2/translate' \
--header 'Authorization: DeepL-Auth-Key <API KEY>' \
--header 'Content-Type: application/json' \
--data '{
  "text": [
    "sit by the bank"
  ],
  "target_lang": "ZH"
}'

curl -X POST 'https://api-free.deepl.com/v2/translate' \
--header 'Authorization: DeepL-Auth-Key <API KEY>' \
--header 'Content-Type: application/json' \
--data '{
  "text": [
    "sit by the bank"
  ],
  "target_lang": "ZH",
  "context": "river"
}'

curl -X POST 'https://api-free.deepl.com/v2/translate' \
--header 'Authorization: DeepL-Auth-Key <API KEY>' \
--header 'Content-Type: application/json' \
--data '{
  "text": [
    "sit by the bank"
  ],
  "target_lang": "ZH",
  "context": "money"
}'

image

官方也说了The context parameter is an alpha feature, meaning it could be deprecated without advance notice. If we do deprecate the feature, requests using the context parameter will not break, and the context will simply be ignored. ,即这个功能后期可能能会被弃用。

@cr7258
Copy link
Collaborator

cr7258 commented Jul 31, 2024

@urlyy Ok, 那至少 context 目前还是有一定作用的,可以在请求的时候把 system prompt 拿到设置到 context 里。

@cr7258
Copy link
Collaborator

cr7258 commented Jul 31, 2024

DeepL有Pro和Free两种API,每个账号好像是只能用对应的API,不能切换。所以model字段我就用去表示别的了。而model_mapping也没用了。同时对于选用哪个版本的API,我添加了一个新配置参数deeplVersion。

model 可以是 pro 和 free,根据 pro 和 free 设置请求的 API URL,这样就不需要额外的参数 deeplVersion 了。

@cr7258
Copy link
Collaborator

cr7258 commented Jul 31, 2024

此处model表示deepl的target_lang,user表示deepl的source_lang。

增加两个配置参数来表示 target_lang 和 source_lang 是不是更好点?

@urlyy
Copy link
Contributor Author

urlyy commented Jul 31, 2024

@cr7258 所以目前就是我们除了text数组外还需要3或4个参数

{
    "model" : "freee', // 这个不属于DeepL的请求参数
    "text": [
        "Hello, world!",
        "你好"
    ],
    "target_lang": "DE",
    "source_lang": "EN", //这个不是必要的,DeepL有一定的识别待翻译文本的语种的能力
    "context": "river",
    
}

但是对于openai协议的request,最外层只有ModelUserString

type chatCompletionRequest struct {
	Model            string         `json:"model"`
	Messages         []chatMessage  `json:"messages"`
	MaxTokens        int            `json:"max_tokens,omitempty"`
	FrequencyPenalty float64        `json:"frequency_penalty,omitempty"`
	N                int            `json:"n,omitempty"`
	PresencePenalty  float64        `json:"presence_penalty,omitempty"`
	Seed             int            `json:"seed,omitempty"`
	Stream           bool           `json:"stream,omitempty"`
	StreamOptions    *streamOptions `json:"stream_options,omitempty"`
	Temperature      float64        `json:"temperature,omitempty"`
	TopP             float64        `json:"top_p,omitempty"`
	Tools            []tool         `json:"tools,omitempty"`
	ToolChoice       *toolChoice    `json:"tool_choice,omitempty"`
	User             string         `json:"user,omitempty"`
	Stop             []string       `json:"stop,omitempty"`
}

type chatMessage struct {
	Name      string     `json:"name,omitempty"`
	Role      string     `json:"role,omitempty"`
	Content   string     `json:"content,omitempty"`
	ToolCalls []toolCall `json:"tool_calls,omitempty"`
}

type streamOptions struct {
	IncludeUsage bool `json:"include_usage,omitempty"`
}

type tool struct {
	Type     string   `json:"type"`
	Function function `json:"function"`
}

type function struct {
	Description string                 `json:"description,omitempty"`
	Name        string                 `json:"name"`
	Parameters  map[string]interface{} `json:"parameters,omitempty"`
}

type toolChoice struct {
	Type     string   `json:"type"`
	Function function `json:"function"`
}

如果不加入新参数,可能就复用Tools []tool。缺点就是tool、function的作用与自己的名词不太相符,然后嵌套结构容易写错。主要是chatCompletionRequest没有一个extra_params : map[string]interface{}这种参数。

chatCompletionRequest: {
    ... ...
    "tools": [
        {
            "function": {
                "name": "model",
                "description": "free"
            }
        },
        {
            "function": {
                "name": "context",
                "description": "river"
            }
        }
    ]
}

我是不太想代理一个不太像LLM的服务反而影响其他正常代理,包括还有我对main.go里请求头检查顺序的调整。

@cr7258
Copy link
Collaborator

cr7258 commented Jul 31, 2024

@urlyy 我的意思是把配置参数加在这里

type ProviderConfig struct {
// @Title zh-CN AI服务提供商
// @Description zh-CN AI服务提供商类型
typ string `required:"true" yaml:"type" json:"type"`
// @Title zh-CN API Tokens
// @Description zh-CN 在请求AI服务时用于认证的API Token列表。不同的AI服务提供商可能有不同的名称。部分供应商只支持配置一个API Token(如Azure OpenAI)。
apiTokens []string `required:"false" yaml:"apiToken" json:"apiTokens"`
// @Title zh-CN 请求超时
// @Description zh-CN 请求AI服务的超时时间,单位为毫秒。默认值为120000,即2分钟
timeout uint32 `required:"false" yaml:"timeout" json:"timeout"`
// @Title zh-CN Moonshot File ID
// @Description zh-CN 仅适用于Moonshot AI服务。Moonshot AI服务的文件ID,其内容用于补充AI请求上下文
moonshotFileId string `required:"false" yaml:"moonshotFileId" json:"moonshotFileId"`
// @Title zh-CN Azure OpenAI Service URL
// @Description zh-CN 仅适用于Azure OpenAI服务。要请求的OpenAI服务的完整URL,包含api-version等参数
azureServiceUrl string `required:"false" yaml:"azureServiceUrl" json:"azureServiceUrl"`
// @Title zh-CN 通义千问File ID
// @Description zh-CN 仅适用于通义千问服务。上传到Dashscope的文件ID,其内容用于补充AI请求上下文。仅支持qwen-long模型。
qwenFileIds []string `required:"false" yaml:"qwenFileIds" json:"qwenFileIds"`
// @Title zh-CN 启用通义千问搜索服务
// @Description zh-CN 仅适用于通义千问服务,表示是否启用通义千问的互联网搜索功能。
qwenEnableSearch bool `required:"false" yaml:"qwenEnableSearch" json:"qwenEnableSearch"`
// @Title zh-CN Ollama Server IP/Domain
// @Description zh-CN 仅适用于 Ollama 服务。Ollama 服务器的主机地址。
ollamaServerHost string `required:"false" yaml:"ollamaServerHost" json:"ollamaServerHost"`
// @Title zh-CN Ollama Server Port
// @Description zh-CN 仅适用于 Ollama 服务。Ollama 服务器的端口号。
ollamaServerPort uint32 `required:"false" yaml:"ollamaServerPort" json:"ollamaServerPort"`
// @Title zh-CN hunyuan api key for authorization
// @Description zh-CN 仅适用于Hun Yuan AI服务鉴权,API key/id 参考:https://cloud.tencent.com/document/api/1729/101843#Golang
hunyuanAuthKey string `required:"false" yaml:"hunyuanAuthKey" json:"hunyuanAuthKey"`
// @Title zh-CN hunyuan api id for authorization
// @Description zh-CN 仅适用于Hun Yuan AI服务鉴权
hunyuanAuthId string `required:"false" yaml:"hunyuanAuthId" json:"hunyuanAuthId"`
// @Title zh-CN minimax group id
// @Description zh-CN 仅适用于minimax使用ChatCompletion Pro接口的模型
minimaxGroupId string `required:"false" yaml:"minimaxGroupId" json:"minimaxGroupId"`
// @Title zh-CN 模型名称映射表
// @Description zh-CN 用于将请求中的模型名称映射为目标AI服务商支持的模型名称。支持通过“*”来配置全局映射
modelMapping map[string]string `required:"false" yaml:"modelMapping" json:"modelMapping"`
// @Title zh-CN 对外接口协议
// @Description zh-CN 通过本插件对外提供的AI服务接口协议。默认值为“openai”,即OpenAI的接口协议。如需保留原有接口协议,可配置为“original"
protocol string `required:"false" yaml:"protocol" json:"protocol"`
// @Title zh-CN 模型对话上下文
// @Description zh-CN 配置一个外部获取对话上下文的文件来源,用于在AI请求中补充对话上下文
context *ContextConfig `required:"false" yaml:"context" json:"context"`
// @Title zh-CN 版本
// @Description zh-CN 请求AI服务的版本,目前仅适用于Claude AI服务
claudeVersion string `required:"false" yaml:"version" json:"version"`
// @Title zh-CN Cloudflare Account ID
// @Description zh-CN 仅适用于 Cloudflare Workers AI 服务。参考:https://developers.cloudflare.com/workers-ai/get-started/rest-api/#2-run-a-model-via-api
cloudflareAccountId string `required:"false" yaml:"cloudflareAccountId" json:"cloudflareAccountId"`
// @Title zh-CN deepl版本
// @Description zh-CN deepl服务的版本,仅适用于DeepL 服务。默认值为“Free”,也可配置为“Pro”。参考:https://developers.deepl.com/docs/v/zh/api-reference/translate
deeplVersion string `required:"false" yaml:"deeplVersion" json:"deeplVersion"`
}

@urlyy
Copy link
Contributor Author

urlyy commented Aug 2, 2024

@urlyy 我的意思是把配置参数加在这里

这样不支持用户自己更改翻译语种吧?

@cr7258
Copy link
Collaborator

cr7258 commented Aug 2, 2024

这样不支持用户自己更改翻译语种吧?

是的,这样就只能根据配置来设置翻译语种了。

但是这样感觉起码比把 target_lang 和 source_lang 设置到不相干的 model 和 user 字段里好点。。。

@urlyy
Copy link
Contributor Author

urlyy commented Aug 4, 2024

@cr7258 这次将版本放在Model字段上了,然后添加了targetLang的配置字段。OverwriteRequestHost放在了OnRequestBody里。

问题就是

  1. 为了使用util.OverwriteRequestAuthorization,我更新了我的fork分支。然而现在的deepl插件代码在之前的分支上能跑,最新的反而不行了,似乎在进入OnRequestBody前阻塞了
  2. OverwriteRequestHost放在OnRequestBody里不能修改请求host

@cr7258
Copy link
Collaborator

cr7258 commented Aug 6, 2024

为了使用util.OverwriteRequestAuthorization,我更新了我的fork分支。然而现在的deepl插件代码在之前的分支上能跑,最新的反而不行了,似乎在进入OnRequestBody前阻塞了
OverwriteRequestHost放在OnRequestBody里不能修改请求host

@urlyy

  1. 需要在 OnRequestHeaders 阶段返回 types.HeaderStopIteration,这样可以在 OnRequestBody 处理 header。
  2. 编译的时候需要带上 EXTRA_TAGS=proxy_wasm_version_0_2_100,比如在 plugins/wasm-go 目录下执行:
PLUGIN_NAME=ai-proxy EXTRA_TAGS=proxy_wasm_version_0_2_100  make build
  1. Envoy 镜像使用:higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/gateway:1.4.0-rc.1

详情参考:#974 (comment)

@johnlanni
Copy link
Collaborator

@urlyy Please resolve the conflicts

@codecov-commenter
Copy link

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 35.96%. Comparing base (ef31e09) to head (b28e307).
Report is 36 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1147      +/-   ##
==========================================
+ Coverage   35.91%   35.96%   +0.05%     
==========================================
  Files          69       69              
  Lines       11576     9500    -2076     
==========================================
- Hits         4157     3417     -740     
+ Misses       7104     5767    -1337     
- Partials      315      316       +1     

see 67 files with indirect coverage changes

@urlyy
Copy link
Contributor Author

urlyy commented Aug 9, 2024

@cr7258 我根据这个方法:#974 (comment) 来弄的话,还是没有进入onRequestBody,但我感觉代码没问题了,能麻烦您能帮我测试一下吗?apikey是5f9068e4-2fd6-4b7e-a103-15858be11918:fx,账号是租的所以问题不大。
然后github action测试没通过?我没看懂失败原因

@cr7258
Copy link
Collaborator

cr7258 commented Aug 14, 2024

还是没有进入onRequestBody

可能是你编译的命令不对?如果用了 HeaderStopIteration,编译的时候要带上 EXTRA_TAGS=proxy_wasm_version_0_2_100。
@urlyy 我刚试了下是可以正常返回结果的:

curl --location 'http://127.0.0.1:10000/v1/chat/completions' \
--header 'Content-Type:  application/json' \
--data '{
    "model":"Free",
    "messages": [
        {
            "role": "system",
            "content": "money"
        },
        {
            "content": "sit by the bank"
        }
    ]
}'
{"choices":[{"index":0,"message":{"name":"EN","role":"assistant","content":"坐庄"}}],"created":1723639642,"model":"Free","object":"chat.completion","usage":{}}

另外我重跑了 ci 测试,通过了。

Copy link
Collaborator

@johnlanni johnlanni left a comment

Choose a reason for hiding this comment

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

LGTM

@johnlanni johnlanni merged commit dcea483 into alibaba:main Aug 15, 2024
12 checks passed
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.

5 participants