Skip to content

Commit 7c0d1a6

Browse files
authored
Merge pull request Stack-Cairn#144 from yyg-max/feat/protocol-v2
feat: unify all links on WebSocket+Protobuf (v2), deprecate v1
2 parents 6874e46 + 95cec27 commit 7c0d1a6

121 files changed

Lines changed: 18505 additions & 2345 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jobs:
1818
runs-on: ubuntu-latest
1919
steps:
2020
- uses: actions/checkout@v6
21+
with:
22+
# buf breaking 需要完整历史以对比 origin/main 的 proto 契约。
23+
fetch-depth: 0
2124

2225
- uses: actions/setup-go@v5
2326
with:
@@ -31,14 +34,14 @@ jobs:
3134
- name: Install pnpm
3235
run: npm install -g pnpm@10.32.1
3336

34-
- name: Install protobuf toolchain
37+
- name: Install buf
38+
uses: bufbuild/buf-action@v1
39+
with:
40+
setup_only: true
41+
version: 1.71.0
42+
43+
- name: Install protobuf Go plugins
3544
run: |
36-
sudo apt-get update
37-
sudo apt-get install -y unzip
38-
curl -fsSL -o "$RUNNER_TEMP/protoc.zip" \
39-
https://github.com/protocolbuffers/protobuf/releases/download/v34.0/protoc-34.0-linux-x86_64.zip
40-
unzip -q "$RUNNER_TEMP/protoc.zip" -d "$RUNNER_TEMP/protoc"
41-
echo "$RUNNER_TEMP/protoc/bin" >> "$GITHUB_PATH"
4245
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
4346
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.6.2
4447
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
@@ -49,10 +52,19 @@ jobs:
4952
pnpm install --frozen-lockfile
5053
pnpm build
5154
55+
- name: Proto lint and breaking-change check
56+
run: make proto-check BUF_BREAKING_AGAINST='../../.git#branch=origin/main,subdir=crates/agent-gateway'
57+
5258
- name: Check generated protobuf
5359
run: |
5460
make proto
55-
git diff --exit-code -- crates/agent-gateway/internal/proto/v1
61+
git diff --exit-code -- crates/agent-gateway/internal/proto
62+
63+
- name: Lint gateway
64+
uses: golangci/golangci-lint-action@v8
65+
with:
66+
version: v2.12.2
67+
working-directory: crates/agent-gateway
5668

5769
- name: Test gateway
5870
working-directory: crates/agent-gateway

Cargo.lock

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
AGENT_GUI_DIR := crates/agent-gui
44
AGENT_GATEWAY_DIR := crates/agent-gateway
55
AGENT_GATEWAY_WEB_DIR := $(AGENT_GATEWAY_DIR)/web
6-
AGENT_GATEWAY_PROTO_FILE := proto/v1/gateway.proto
76

87
HOST_ARCH := $(shell uname -m)
98

@@ -33,7 +32,7 @@ RELEASE_TAG ?=
3332

3433
.PHONY: all dev build desktop-build-macos desktop-build-macos-release desktop-build-macos-intel desktop-build-macos-m desktop-build-windows desktop-build-linux github-release-main check-github-release-tag help
3534
.PHONY: dev-gateway dev-webui
36-
.PHONY: proto webui gateway-build gateway-docker-build gateway-docker-run gateway-docker-smoke build-linux build-linux-amd build-linux-arm
35+
.PHONY: proto proto-check webui gateway-build gateway-docker-build gateway-docker-run gateway-docker-smoke build-linux build-linux-amd build-linux-arm
3736
.PHONY: clean check-rust-target-% check-macos-signing-identity check-macos-notary-profile desktop-store-macos-notary-profile desktop-wait-macos-notary desktop-staple-macos desktop-verify-macos
3837

3938
all: build gateway-build
@@ -116,16 +115,16 @@ dev-webui:
116115

117116
## Gateway build and generated assets
118117
proto:
119-
@command -v protoc >/dev/null || (echo "protoc is required" && exit 1)
120-
@command -v protoc-gen-go >/dev/null || (echo "protoc-gen-go is required. Run: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest" && exit 1)
121-
@command -v protoc-gen-go-grpc >/dev/null || (echo "protoc-gen-go-grpc is required. Run: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest" && exit 1)
122-
protoc \
123-
--proto_path=$(AGENT_GATEWAY_DIR) \
124-
--go_out=$(AGENT_GATEWAY_DIR) \
125-
--go_opt=module=github.com/liveagent/agent-gateway \
126-
--go-grpc_out=$(AGENT_GATEWAY_DIR) \
127-
--go-grpc_opt=module=github.com/liveagent/agent-gateway \
128-
$(AGENT_GATEWAY_PROTO_FILE)
118+
@command -v buf >/dev/null || (echo "buf is required. Run: mise install" && exit 1)
119+
cd $(AGENT_GATEWAY_DIR) && buf generate
120+
121+
# buf breaking 的对比基线(本地默认与当前 HEAD 对比;CI 覆写为 origin/main)。
122+
BUF_BREAKING_AGAINST ?= ../../.git#subdir=$(AGENT_GATEWAY_DIR)
123+
124+
proto-check:
125+
@command -v buf >/dev/null || (echo "buf is required. Run: mise install" && exit 1)
126+
cd $(AGENT_GATEWAY_DIR) && buf lint
127+
cd $(AGENT_GATEWAY_DIR) && buf breaking --against '$(BUF_BREAKING_AGAINST)'
129128

130129
webui:
131130
pnpm --dir $(AGENT_GATEWAY_WEB_DIR) install --offline

crates/agent-gateway/.golangci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# golangci-lint v2 —— 网关 Go 代码检查基线(此前无 linter,选务实检查集):govet/staticcheck/unused
2+
# 管正确性与死代码(SA1019 兼作"调用已弃用 v1 符号"提示),errcheck/ineffassign/misspell 做基础卫生。
3+
# 生成代码(internal/proto/)不参与检查。
4+
version: "2"
5+
6+
linters:
7+
default: none
8+
enable:
9+
- govet
10+
- staticcheck
11+
- unused
12+
- errcheck
13+
- ineffassign
14+
- misspell
15+
exclusions:
16+
generated: lax
17+
rules:
18+
# v1 协议实现、其组装点与测试引用弃用 v1 符号是预期行为(整层同生命周期弃用):
19+
# 对这些路径静默 SA1019,避免刷屏。
20+
- path: internal/server/
21+
linters: [staticcheck]
22+
text: "SA1019"
23+
- path: cmd/gateway/
24+
linters: [staticcheck]
25+
text: "SA1019"
26+
- path: test/
27+
linters: [staticcheck]
28+
text: "SA1019"
29+
# 测试代码允许忽略清理类调用的返回值。
30+
- path: _test\.go
31+
linters: [errcheck]
32+
33+
issues:
34+
max-issues-per-linter: 0
35+
max-same-issues: 0

crates/agent-gateway/buf.gen.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# buf 代码生成配置(v2 schema)。Go 插件用 mise 固定版本、`module=` 与历史 protoc 一致,
2+
# 输出 internal/proto/;TS 插件 protoc-gen-es 由 web/node_modules 锁定,输出 web/src/lib/proto/gen/。
3+
version: v2
4+
plugins:
5+
- local: protoc-gen-go
6+
out: .
7+
opt: module=github.com/liveagent/agent-gateway
8+
- local: protoc-gen-go-grpc
9+
out: .
10+
opt: module=github.com/liveagent/agent-gateway
11+
- local: web/node_modules/.bin/protoc-gen-es
12+
out: web/src/lib/proto/gen
13+
opt: target=ts
14+
inputs:
15+
- directory: .

crates/agent-gateway/buf.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# buf 模块配置(v2 schema)。模块根设在 crates/agent-gateway/ 而非 proto/,保持 import 路径
2+
# "proto/v1/gateway.proto" 与历史 protoc 及 Rust build.rs 一致,Go 生成物与既有提交字节级一致。
3+
version: v2
4+
modules:
5+
- path: .
6+
excludes:
7+
# 排除 WebUI node_modules 里的第三方 .proto。
8+
- web
9+
lint:
10+
use:
11+
- STANDARD
12+
except:
13+
# 历史布局 proto/<版本>/ 早于 buf;迁目录会改 import 路径、破坏 Rust build.rs 与生成物,不翻新。
14+
- PACKAGE_DIRECTORY_MATCH
15+
# v1 契约早于 buf lint,历史命名不翻新(wire 兼容优先);豁免为全量 lint 确认后的最小集,
16+
# 仅限 v1 文件——v2 及新增 proto 必须完整满足 STANDARD。
17+
ignore_only:
18+
SERVICE_SUFFIX:
19+
- proto/v1/gateway.proto
20+
RPC_REQUEST_STANDARD_NAME:
21+
- proto/v1/gateway.proto
22+
RPC_RESPONSE_STANDARD_NAME:
23+
- proto/v1/gateway.proto
24+
RPC_REQUEST_RESPONSE_UNIQUE:
25+
- proto/v1/gateway.proto
26+
ENUM_VALUE_PREFIX:
27+
- proto/v1/gateway.proto
28+
ENUM_ZERO_VALUE_SUFFIX:
29+
- proto/v1/gateway.proto
30+
breaking:
31+
use:
32+
# WIRE_JSON:兼守二进制与 JSON 线格式兼容(v1 JSON 协议仍在服务期)。
33+
- WIRE_JSON

crates/agent-gateway/cmd/gateway/main.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"context"
55
"errors"
6-
"log"
6+
"log/slog"
77
"net"
88
"net/http"
99
"os"
@@ -18,25 +18,33 @@ import (
1818

1919
"github.com/liveagent/agent-gateway/internal/auth"
2020
"github.com/liveagent/agent-gateway/internal/config"
21+
"github.com/liveagent/agent-gateway/internal/observability"
2122
gatewayv1 "github.com/liveagent/agent-gateway/internal/proto/v1"
2223
"github.com/liveagent/agent-gateway/internal/server"
2324
"github.com/liveagent/agent-gateway/internal/session"
2425
)
2526

2627
const grpcShutdownTimeout = 3 * time.Second
2728

29+
// fatal 记录错误并以非零码退出(slog 没有 Fatal 级别,集中在此处理)。
30+
func fatal(msg string, args ...any) {
31+
slog.Error(msg, args...)
32+
os.Exit(1)
33+
}
34+
2835
func main() {
36+
observability.SetupLogging()
2937
cfg := config.Load()
3038
sm := session.NewManager()
3139

3240
grpcServer, err := newGRPCServer(cfg, sm)
3341
if err != nil {
34-
log.Fatalf("create gRPC server: %v", err)
42+
fatal("create gRPC server failed", "err", err)
3543
}
3644

3745
grpcListener, err := net.Listen("tcp", cfg.GRPCAddr)
3846
if err != nil {
39-
log.Fatalf("listen gRPC: %v", err)
47+
fatal("listen gRPC failed", "addr", cfg.GRPCAddr, "err", err)
4048
}
4149

4250
httpServer := &http.Server{
@@ -48,14 +56,14 @@ func main() {
4856
errCh := make(chan error, 2)
4957

5058
go func() {
51-
log.Printf("gRPC listening on %s", cfg.GRPCAddr)
59+
slog.Info("gRPC listening", "addr", cfg.GRPCAddr)
5260
if serveErr := grpcServer.Serve(grpcListener); serveErr != nil && !errors.Is(serveErr, grpc.ErrServerStopped) {
5361
errCh <- serveErr
5462
}
5563
}()
5664

5765
go func() {
58-
log.Printf("HTTP listening on %s", cfg.HTTPAddr)
66+
slog.Info("HTTP listening", "addr", cfg.HTTPAddr)
5967
var serveErr error
6068
if cfg.TLSCert != "" || cfg.TLSKey != "" {
6169
serveErr = httpServer.ListenAndServeTLS(cfg.TLSCert, cfg.TLSKey)
@@ -72,9 +80,9 @@ func main() {
7280

7381
select {
7482
case sig := <-signalCh:
75-
log.Printf("received signal %s, shutting down", sig)
83+
slog.Info("received signal, shutting down", "signal", sig.String())
7684
case err := <-errCh:
77-
log.Fatalf("server error: %v", err)
85+
fatal("server error", "err", err)
7886
}
7987

8088
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -86,11 +94,11 @@ func main() {
8694
}()
8795

8896
if forced := shutdownGRPCServer(grpcServer, grpcShutdownTimeout); forced {
89-
log.Printf("gRPC graceful shutdown timed out after %s, forcing stop", grpcShutdownTimeout)
97+
slog.Warn("gRPC graceful shutdown timed out, forcing stop", "timeout", grpcShutdownTimeout)
9098
}
9199

92100
if err := <-httpShutdownErrCh; err != nil {
93-
log.Printf("http shutdown error: %v", err)
101+
slog.Warn("http shutdown error", "err", err)
94102
}
95103
}
96104

0 commit comments

Comments
 (0)