Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Credential files - should never be committed
*.json
!install-gcli2api.sh
!uninstall-gcli2api.sh
!package.json
!package-lock.json
!tsconfig.json
Expand Down
125 changes: 125 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,130 @@
# GeminiCLI to API

> 本仓库维护版:`qingan123/gcli2api`
>
> 支持 Gemini CLI / Antigravity,包含改进后的 Antigravity 流式抗截断续写逻辑。

## ⚡ 一键部署(推荐)

Linux / macOS / WSL:

```bash
curl -fsSL https://raw.githubusercontent.com/qingan123/gcli2api/master/install-gcli2api.sh | bash
```

默认配置:

- 部署目录:`~/gcli2api`
- 端口:`7861`
- 默认密码:`584248`
- 容器启动后会自动检查 `/antigravity/v1/models`

自定义密码、端口和目录:

```bash
PASSWORD='你的密码' PORT=7861 GCLI2API_DIR=/opt/gcli2api \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/qingan123/gcli2api/master/install-gcli2api.sh)"
```

## 🧹 一键卸载

默认卸载容器和服务,但保留凭证数据:

```bash
curl -fsSL https://raw.githubusercontent.com/qingan123/gcli2api/master/uninstall-gcli2api.sh | bash
```

卸载并删除部署目录、凭证和全部数据:

```bash
REMOVE_DATA=1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/qingan123/gcli2api/master/uninstall-gcli2api.sh)"
```

## 🔌 API 接口

公网部署后,将下面的 `HOST` 替换为服务器公网 IP 或域名:

```text
HOST=http://你的公网IP:7861
API_BASE=$HOST/antigravity/v1
PASSWORD=584248
```

### Antigravity OpenAI 兼容接口(推荐)

模型列表:

```http
GET $API_BASE/models
Authorization: Bearer 584248
```

聊天接口:

```http
POST $API_BASE/chat/completions
Authorization: Bearer 584248
Content-Type: application/json
```

请求示例:

```bash
curl "$API_BASE/chat/completions" \
-H "Authorization: Bearer 584248" \
-H 'Content-Type: application/json' \
-d '{
"model": "gemini-2.5-flash",
"messages": [{"role": "user", "content": "你好"}],
"stream": false
}'
```

### 抗截断请求

抗截断仅对流式请求启用,模型名前加 `抗截断/`:

```bash
curl "$API_BASE/chat/completions" \
-H "Authorization: Bearer 584248" \
-H 'Content-Type: application/json' \
-d '{
"model": "抗截断/gemini-2.5-flash",
"messages": [{"role": "user", "content": "写一篇长文章"}],
"stream": true
}'
```

### Antigravity Gemini 原生接口

```http
POST $API_BASE/models/{model}:generateContent
Authorization: Bearer 584248
Content-Type: application/json
```

### Antigravity Claude 兼容接口

```http
POST $API_BASE/messages
Authorization: Bearer 584248
Content-Type: application/json
```

### Gemini CLI 接口

如果上传的是 Gemini CLI 凭证而不是 Antigravity 凭证,使用:

```text
http://你的公网IP:7861/v1
```

Antigravity 凭证必须使用:

```text
http://你的公网IP:7861/antigravity/v1
```

**将 GeminiCLI 和 Antigravity 转换为 OpenAI 、GEMINI 和 Claude API 兼容接口**

[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
Expand Down
59 changes: 59 additions & 0 deletions install-gcli2api.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
set -Eeuo pipefail

# One-click deployment for qingan123/gcli2api.
# Usage: curl -fsSL https://raw.githubusercontent.com/qingan123/gcli2api/master/install-gcli2api.sh | bash

APP_DIR="${GCLI2API_DIR:-$HOME/gcli2api}"
PORT="${PORT:-7861}"
PASSWORD="${PASSWORD:-584248}"
REPO_URL="${GCLI2API_REPO:-https://github.com/qingan123/gcli2api.git}"
BRANCH="${GCLI2API_BRANCH:-master}"

if ! command -v docker >/dev/null 2>&1; then
printf '%s\n' '错误:未检测到 Docker,请先安装 Docker Engine 和 Docker Compose。' >&2
exit 1
fi
if ! docker compose version >/dev/null 2>&1; then
printf '%s\n' '错误:未检测到 Docker Compose v2。' >&2
exit 1
fi

mkdir -p "$APP_DIR/data/creds"
if [ -d "$APP_DIR/.git" ]; then
git -C "$APP_DIR" fetch origin "$BRANCH"
git -C "$APP_DIR" checkout "$BRANCH"
git -C "$APP_DIR" reset --hard "origin/$BRANCH"
else
tmp_dir="${APP_DIR}.tmp.$$"
rm -rf "$tmp_dir"
git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$tmp_dir"
if [ -d "$APP_DIR/data/creds" ]; then
cp -a "$APP_DIR/data/creds/." "$tmp_dir/data/creds/" 2>/dev/null || true
fi
rm -rf "$APP_DIR"
mv "$tmp_dir" "$APP_DIR"
fi

mkdir -p "$APP_DIR/data/creds"
cat > "$APP_DIR/.env" <<EOF
PASSWORD=$PASSWORD
API_PASSWORD=$PASSWORD
PANEL_PASSWORD=$PASSWORD
PORT=$PORT
HOST=0.0.0.0
EOF
chmod 600 "$APP_DIR/.env"

cd "$APP_DIR"
docker compose build --pull
docker compose up -d --force-recreate
sleep 3
curl -fsS -H "Authorization: Bearer $PASSWORD" "http://127.0.0.1:$PORT/antigravity/v1/models" >/dev/null

printf '\n部署完成\n'
printf '目录: %s\n' "$APP_DIR"
printf '面板: http://%s:%s\n' "$(hostname -I | awk '{print $1}')" "$PORT"
printf 'Antigravity API: http://%s:%s/antigravity/v1\n' "$(hostname -I | awk '{print $1}')" "$PORT"
printf '密码: %s\n' "$PASSWORD"
printf '验证: HTTP 200\n'
4 changes: 3 additions & 1 deletion src/router/antigravity/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ async def stream_request_wrapper(payload):
stream_request_wrapper,
anti_truncation_payload,
max_attempts,
enable_prefill_mode=("claude" not in str(api_request.get("model", "")).lower()),
# Antigravity may ignore model prefill and finish immediately. Use an
# explicit continuation user message so plain-text fallback can resume.
enable_prefill_mode=False,
)

# 转换为 OpenAI 格式
Expand Down
27 changes: 27 additions & 0 deletions uninstall-gcli2api.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -Eeuo pipefail

# One-click uninstall. Credentials are preserved by default.
# Set REMOVE_DATA=1 to remove credentials and local deployment data too.

APP_DIR="${GCLI2API_DIR:-$HOME/gcli2api}"
REMOVE_DATA="${REMOVE_DATA:-0}"

if [ ! -d "$APP_DIR" ]; then
printf '未找到部署目录: %s\n' "$APP_DIR"
exit 0
fi

if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1 && [ -f "$APP_DIR/docker-compose.yml" ]; then
docker compose -f "$APP_DIR/docker-compose.yml" down --remove-orphans || true
fi

if [ "$REMOVE_DATA" = "1" ]; then
rm -rf "$APP_DIR"
printf '已卸载并删除部署目录及凭证数据: %s\n' "$APP_DIR"
else
rm -f "$APP_DIR/.env"
rm -rf "$APP_DIR/.git" "$APP_DIR"/source-inspect
printf '已卸载服务;凭证数据保留在: %s/data/creds\n' "$APP_DIR"
printf '如需删除凭证和全部数据,请执行: REMOVE_DATA=1 %s\n' "$0"
fi