Skip to content

Commit 63aae07

Browse files
committed
Add continuity and inference execution tests, implement state management
- Introduced `continuity_e2e_test.go` to validate end-to-end continuity scenarios, ensuring proper state handling across tenant boundaries. - Added `continuity_test.go` for unit tests on continuity state persistence, corruption handling, and opaque state token management. - Implemented `inference_execution.go` to manage inference execution, including state binding and continuity logic. - Created `tenant.go` to manage tenant context within requests, ensuring proper isolation and handling of tenant namespaces. - Enhanced state token management in responses, ensuring secure handling of opaque tokens and previous response IDs.
1 parent 1142b7f commit 63aae07

47 files changed

Lines changed: 13791 additions & 586 deletions

Some content is hidden

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

‎.env.example‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ GROK_RETRY_BASE_DELAY=200ms
1111
GROK_RATE_LIMIT_COOLDOWN=1m
1212
# 上游账号或免费模型额度耗尽后的默认冷却时间
1313
GROK_QUOTA_COOLDOWN=24h
14-
# 会话与上游账号亲和关系在内存中的有效时间
14+
# 会话与上游账号亲和关系的有效时间;hard binding 会哈希化持久保存,soft binding 仅在内存中
1515
GROK_AFFINITY_TTL=1h
16-
# 内存中最多保存的会话亲和关系数量
16+
# 最多保存的会话亲和关系数量
1717
GROK_AFFINITY_MAX_ENTRIES=100000
1818

1919

2020
# 可选。留空(默认)表示不启用访问控制。设置后,受保护的 API 和上游透传接口
2121
# 必须携带 `Authorization: Bearer <key>`、`x-api-key: <key>` 或
2222
# `api-key: <key>`。OpenAI SDK 客户端会自动将 `api_key` 参数作为 Bearer 令牌发送
23-
# 支持配置多个 Key,可为每个客户端分配独立 Key,无需重启服务
23+
# 支持配置多个 Key,可为每个客户端分配独立 Key。
24+
# 每个 Key 还会派生独立的 tenant namespace;不配置 Key 时所有调用方共享 public tenant。
2425

2526
GROK_API_KEYS=key1,key2,key3
2627

@@ -30,16 +31,17 @@ GROK_API_KEYS=key1,key2,key3
3031
GROK_ADMIN_KEY=
3132

3233

33-
# 每个账号对应一个 OAuth JSON 凭证文件,并直接放入此目录,支持直接导入CPA格式的凭证
34-
# 文件支持热加载,刷新后的令牌会写回。
34+
# 直接放入 Grok CLI auth.json 或兼容凭证,支持旧单凭证、tokens 包装和多 scope 文件。
35+
# 文件支持热加载;刷新时只在文件锁内原子更新目标 scope。state v2 与哈希化 hard affinity
36+
# 也保存在此目录,因此目录必须可写。
3537
GROK_AUTHS_DIR=./auths
3638
# 扫描凭证目录并热加载新增、更新或删除文件的时间间隔
3739
GROK_AUTHS_RELOAD_INTERVAL=30s
3840
# 同时执行 OAuth 令牌刷新的最大并发数
3941
GROK_AUTH_REFRESH_CONCURRENCY=4
4042
# 每个账号允许同时发往上游的最大请求数。超出的请求会等待其他账号或已释放的容量,
41-
GROK_ACCOUNT_MAX_INFLIGHT=8
42-
# 按此时间间隔刷新每个账号持久化保存的上游模型目录。
43+
GROK_ACCOUNT_MAX_INFLIGHT=16
44+
# 按此时间间隔刷新 state v2 中每个账号的结构化上游模型目录与 ETag。
4345
GROK_MODELS_REFRESH_INTERVAL=6h
4446

4547

@@ -69,14 +71,20 @@ GROK_MODELS_REFRESH_INTERVAL=6h
6971
# Grok CLI 连接的地址
7072
GROK_CHAT_PROXY_BASE_URL=https://cli-chat-proxy.grok.com
7173
GROK_CHAT_PROXY_VERSION=v1
74+
# API Key 账号固定使用运维配置的 xAI API origin,远端模型字段不能覆盖
75+
GROK_XAI_API_BASE_URL=https://api.x.ai
7276
# 流式传输默认使用 identity,避免 gzip 层缓冲较小的 SSE 事件
7377
# 仅在需要兼容性回退时设置为 gzip
7478
GROK_STREAM_COMPRESSION=identity
7579
# 如果上游返回 HTTP 426,并要求更高的最低版本,请更新此值
76-
GROK_CLIENT_VERSION=0.2.93
80+
GROK_CLIENT_VERSION=0.2.102
7781
GROK_CLIENT_SURFACE=tui
82+
# 默认使用非交互的 headless 客户端模式;可选 interactive
83+
GROK_CLIENT_MODE=headless
7884
GROK_CLIENT_IDENTIFIER=grok-shell
7985
GROK_TOKEN_AUTH=xai-grok-cli
86+
# 可选的托管部署标识
87+
# GROK_DEPLOYMENT_ID=
8088
# x-grok-* 请求头配置
8189
GROK_CLIENT_NAME=grok-shell
8290
# 仅可在受控调试环境中关闭 TLS 证书验证

‎.github/workflows/ci.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ jobs:
2323
cache: false
2424
- name: Check formatting
2525
shell: bash
26-
run: test -z "$(gofmt -l .)"
26+
run: test -z "$(gofmt -l $(git ls-files '*.go'))"
2727
- name: Test
28-
run: go test ./...
28+
run: go test -count=1 ./...
2929
- name: Race detector
3030
if: runner.os == 'Linux'
31-
run: go test -race ./...
31+
run: go test -race -count=1 ./...
3232
- name: Vet
3333
run: go vet ./...
3434
- name: Build
35-
run: go build ./cmd/grok2api
35+
run: go build -trimpath ./cmd/grok2api
3636

3737
docker:
3838
needs: test

‎CONTRIBUTING.md‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,28 @@ Thanks for contributing to `grokcli2api-go`.
77
Requirements: Go 1.23 or newer.
88

99
```bash
10-
go test ./...
10+
test -z "$(gofmt -l $(git ls-files '*.go'))"
11+
go test -count=1 ./...
12+
go test -race -count=1 ./... # Linux
1113
go vet ./...
12-
go build ./cmd/grok2api
14+
go build -trimpath ./cmd/grok2api
15+
docker build .
1316
```
1417

1518
Run `gofmt` on changed Go files. Keep the production implementation on the Go standard library unless a dependency is clearly justified.
1619

20+
## Live smoke
21+
22+
The real inference smoke is disabled by default. Run it only after every offline gate above has passed, including Linux race testing and the Docker build:
23+
24+
```bash
25+
GROK_LIVE_SMOKE=1 \
26+
GROK_LIVE_SMOKE_OFFLINE_GATES=passed \
27+
go test -count=1 -run '^TestLiveInferenceSmoke$' ./internal/grok
28+
```
29+
30+
It reads `auths/live-01.json` by default; set `GROK_LIVE_SMOKE_AUTH_FILE` to use another file. The source must resolve to exactly one logical credential so initialization performs one account catalog discovery. The smoke gives the service only a temporary `0600` copy with refresh tokens, ID tokens, email fields, and stale legacy model lists removed. It refuses access tokens with less than ten minutes remaining and fails if the source credential hash or Git worktree changes. Response bodies, tokens, and account identifiers are never printed.
31+
1732
## Pull requests
1833

1934
- Keep changes focused and describe protocol compatibility implications.

‎Dockerfile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ WORKDIR /src
33
COPY go.mod ./
44
COPY cmd ./cmd
55
COPY internal ./internal
6-
RUN CGO_ENABLED=0 go test ./... && \
6+
RUN CGO_ENABLED=0 go test -count=1 ./... && \
77
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/grok2api ./cmd/grok2api
88

99
FROM alpine:3.22

0 commit comments

Comments
 (0)